interp: fix default type for constants from runtime
The default type must be derived from the constant value when necessary, otherwise the type check fails wrongly. Fixes #1026.
This commit is contained in:
11
_test/time16.go
Normal file
11
_test/time16.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
func main() {
|
||||
localTime := time.ANSIC
|
||||
println(localTime)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Mon Jan _2 15:04:05 2006
|
||||
@@ -1502,10 +1502,25 @@ func (t *itype) implements(it *itype) bool {
|
||||
}
|
||||
|
||||
// defaultType returns the default type of an untyped type.
|
||||
func (t *itype) defaultType() *itype {
|
||||
func (t *itype) defaultType(v reflect.Value) *itype {
|
||||
if !t.untyped {
|
||||
return t
|
||||
}
|
||||
// The default type can also be derived from a constant value.
|
||||
if v.IsValid() && t.TypeOf().Implements(constVal) {
|
||||
switch v.Interface().(constant.Value).Kind() {
|
||||
case constant.String:
|
||||
t = untypedString()
|
||||
case constant.Bool:
|
||||
t = untypedBool()
|
||||
case constant.Int:
|
||||
t = untypedInt()
|
||||
case constant.Float:
|
||||
t = untypedFloat()
|
||||
case constant.Complex:
|
||||
t = untypedComplex()
|
||||
}
|
||||
}
|
||||
typ := *t
|
||||
typ.untyped = false
|
||||
return &typ
|
||||
|
||||
@@ -37,7 +37,7 @@ func (check typecheck) assignment(n *node, typ *itype, context string) error {
|
||||
if typ == nil && n.typ.cat == nilT {
|
||||
return n.cfgErrorf("use of untyped nil in %s", context)
|
||||
}
|
||||
typ = n.typ.defaultType()
|
||||
typ = n.typ.defaultType(n.rval)
|
||||
}
|
||||
if err := check.convertUntyped(n, typ); err != nil {
|
||||
return err
|
||||
@@ -65,7 +65,7 @@ func (check typecheck) assignExpr(n, dest, src *node) error {
|
||||
isConst := n.anc.kind == constDecl
|
||||
if !isConst {
|
||||
// var operations must be typed
|
||||
dest.typ = dest.typ.defaultType()
|
||||
dest.typ = dest.typ.defaultType(src.rval)
|
||||
}
|
||||
|
||||
return check.assignment(src, dest.typ, "assignment")
|
||||
@@ -636,7 +636,7 @@ func (check typecheck) conversion(n *node, typ *itype) error {
|
||||
return nil
|
||||
}
|
||||
if isInterface(typ) || !isConstType(typ) {
|
||||
typ = n.typ.defaultType()
|
||||
typ = n.typ.defaultType(n.rval)
|
||||
}
|
||||
return check.convertUntyped(n, typ)
|
||||
}
|
||||
@@ -1037,9 +1037,8 @@ func (check typecheck) convertUntyped(n *node, typ *itype) error {
|
||||
if len(n.typ.methods()) > 0 { // untyped cannot be set to iface
|
||||
return convErr
|
||||
}
|
||||
ityp = n.typ.defaultType()
|
||||
ityp = n.typ.defaultType(n.rval)
|
||||
rtyp = ntyp
|
||||
|
||||
case isArray(typ) || isMap(typ) || isChan(typ) || isFunc(typ) || isPtr(typ):
|
||||
// TODO(nick): above we are acting on itype, but really it is an rtype check. This is not clear which type
|
||||
// plain we are in. Fix this later.
|
||||
|
||||
Reference in New Issue
Block a user