interp: allow conversions of untyped complex
For untyped numerical types, conversions to different numerical types can be allowed if there is no overflow (not checked here). Fixes #1402.
This commit is contained in:
@@ -176,7 +176,7 @@ func TestEvalBuiltin(t *testing.T) {
|
||||
{src: `m := complex(3, 2); real(m)`, res: "3"},
|
||||
{src: `m := complex(3, 2); imag(m)`, res: "2"},
|
||||
{src: `m := complex("test", 2)`, err: "1:33: invalid types string and int"},
|
||||
{src: `imag("test")`, err: "1:33: cannot convert \"test\" to complex128"},
|
||||
{src: `imag("test")`, err: "1:33: cannot convert untyped string to untyped complex"},
|
||||
{src: `imag(a)`, err: "1:33: invalid argument type []int for imag"},
|
||||
{src: `real(a)`, err: "1:33: invalid argument type []int for real"},
|
||||
{src: `t := map[int]int{}; t[123]++; t`, res: "map[123:1]"},
|
||||
@@ -184,6 +184,9 @@ func TestEvalBuiltin(t *testing.T) {
|
||||
{src: `t := map[int]int{}; t[123] += 1; t`, res: "map[123:1]"},
|
||||
{src: `t := map[int]int{}; t[123] -= 1; t`, res: "map[123:-1]"},
|
||||
{src: `println("hello", _)`, err: "1:28: cannot use _ as value"},
|
||||
{src: `f := func() complex64 { return complex(0, 0) }()`, res: "(0+0i)"},
|
||||
{src: `f := func() float32 { return real(complex(2, 1)) }()`, res: "2"},
|
||||
{src: `f := func() int8 { return imag(complex(2, 1)) }()`, res: "1"},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -585,12 +585,12 @@ func nodeType2(interp *Interpreter, sc *scope, n *node, seen []*node) (t *itype,
|
||||
}
|
||||
if !t.incomplete {
|
||||
switch k := t.TypeOf().Kind(); {
|
||||
case t.untyped && isNumber(t.TypeOf()):
|
||||
t = untypedFloat()
|
||||
case k == reflect.Complex64:
|
||||
t = sc.getType("float32")
|
||||
case k == reflect.Complex128:
|
||||
t = sc.getType("float64")
|
||||
case t.untyped && isNumber(t.TypeOf()):
|
||||
t = valueTOf(floatType, withUntyped(true), withScope(sc))
|
||||
default:
|
||||
err = n.cfgErrorf("invalid complex type %s", k)
|
||||
}
|
||||
@@ -1219,6 +1219,11 @@ func (t *itype) assignableTo(o *itype) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if t.untyped && isNumber(t.TypeOf()) && isNumber(o.TypeOf()) {
|
||||
// Assignability depends on constant numeric value (overflow check), to be tested elsewhere.
|
||||
return true
|
||||
}
|
||||
|
||||
n := t.node
|
||||
if n == nil || !n.rval.IsValid() {
|
||||
return false
|
||||
|
||||
@@ -815,7 +815,7 @@ func (check typecheck) builtin(name string, n *node, child []*node, ellipsis boo
|
||||
case !typ0.untyped && typ1.untyped:
|
||||
err = check.convertUntyped(p1.nod, typ0)
|
||||
case typ0.untyped && typ1.untyped:
|
||||
fltType := check.scope.getType("float64")
|
||||
fltType := untypedFloat()
|
||||
err = check.convertUntyped(p0.nod, fltType)
|
||||
if err != nil {
|
||||
break
|
||||
@@ -838,7 +838,7 @@ func (check typecheck) builtin(name string, n *node, child []*node, ellipsis boo
|
||||
p := params[0]
|
||||
typ := p.Type()
|
||||
if typ.untyped {
|
||||
if err := check.convertUntyped(p.nod, check.scope.getType("complex128")); err != nil {
|
||||
if err := check.convertUntyped(p.nod, untypedComplex()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user