From 16007aade37805e8aecab4069fb7564173352734 Mon Sep 17 00:00:00 2001 From: visualfc Date: Thu, 5 Dec 2024 16:09:38 +0800 Subject: [PATCH] AssignableConv check underlying basic --- builtin_test.go | 19 +++++++++++++++++++ template.go | 38 +++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/builtin_test.go b/builtin_test.go index 797dbf92..7a657ff8 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -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") + } +} + // ---------------------------------------------------------------------------- diff --git a/template.go b/template.go index fa26a8ad..7e24ed07 100644 --- a/template.go +++ b/template.go @@ -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) @@ -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 {