Skip to content

Commit

Permalink
Merge pull request #453 from visualfc/conv
Browse files Browse the repository at this point in the history
AssignableConv check underlying basic
  • Loading branch information
xushiwei authored Dec 5, 2024
2 parents 5fe0662 + 16007aa commit ac870e2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
19 changes: 19 additions & 0 deletions builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1341,4 +1341,23 @@ func TestToTag(t *testing.T) {
}
}

func TestAssignableUntyped(t *testing.T) {
f64 := types.NewNamed(types.NewTypeName(token.NoPos, nil, "Float64", nil),
types.Typ[types.UntypedFloat], nil)
i64 := types.NewNamed(types.NewTypeName(token.NoPos, nil, "Int64", nil),
types.Typ[types.UntypedInt], nil)
if assignableTo(f64, types.Typ[types.UntypedInt], nil) {
t.Fatal("error f2i")
}
if !assignableTo(f64, types.Typ[types.UntypedFloat], nil) {
t.Fatal("must f2f")
}
if !assignableTo(i64, types.Typ[types.UntypedInt], nil) {
t.Fatal("must i2i")
}
if !assignableTo(i64, types.Typ[types.UntypedFloat], nil) {
t.Fatal("must i2f")
}
}

// ----------------------------------------------------------------------------
38 changes: 21 additions & 17 deletions template.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,26 @@ func AssignableConv(pkg *Package, V, T types.Type, pv *Element) bool {
V = getElemTypeIf(V, pv)
}
if types.AssignableTo(V, T) {
if t, ok := T.(*types.Basic); ok { // untyped type
vkind := V.(*types.Basic).Kind()
tkind := t.Kind()
switch {
case vkind >= types.UntypedInt && vkind <= types.UntypedComplex:
return assignableTo(V, T, pv)
}
if t, ok := T.(*types.Named); ok {
ok = assignable(pkg, V, t, pv)
if debugMatch && pv != nil {
log.Println("==> AssignableConv", V, T, ok)
}
return ok
}
if pkg.implicitCast != nil {
return pkg.implicitCast(pkg, V, T, pv)
}
return false
}

func assignableTo(V, T types.Type, pv *Element) bool {
if t, ok := T.Underlying().(*types.Basic); ok { // untyped type
if v, ok := V.Underlying().(*types.Basic); ok {
tkind, vkind := t.Kind(), v.Kind()
if vkind >= types.UntypedInt && vkind <= types.UntypedComplex {
if tkind <= types.Uintptr && pv != nil && outOfRange(tkind, pv.CVal) {
if debugMatch {
log.Printf("==> AssignableConv %v (%v): value is out of %v range", V, pv.CVal, T)
Expand All @@ -290,19 +305,8 @@ func AssignableConv(pkg *Package, V, T types.Type, pv *Element) bool {
}
}
}
return true
}
if t, ok := T.(*types.Named); ok {
ok = assignable(pkg, V, t, pv)
if debugMatch && pv != nil {
log.Println("==> AssignableConv", V, T, ok)
}
return ok
}
if pkg.implicitCast != nil {
return pkg.implicitCast(pkg, V, T, pv)
}
return false
return true
}

func outOfRange(tkind types.BasicKind, cval constant.Value) bool {
Expand Down

0 comments on commit ac870e2

Please sign in to comment.