diff --git a/_test/composite15.go b/_test/composite15.go new file mode 100644 index 00000000..afb7f553 --- /dev/null +++ b/_test/composite15.go @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" +) + +func interfaceAsInts() { + var a interface{} + b := 2 + c := 3 + a = []int{b, c} + + d, ok := a.([]int) + if !ok { + println("nope") + return + } + + for _, v := range d { + fmt.Println(v) + } +} + +func interfaceAsInterfaces() { + var a, b, c interface{} + b = 2 + c = 3 + a = []interface{}{b, c} + + d, ok := a.([]interface{}) + if !ok { + println("nope") + return + } + + for _, v := range d { + fmt.Println(v) + } +} + +func main() { + interfaceAsInts() + interfaceAsInterfaces() +} + +// Output: +// 2 +// 3 +// 2 +// 3 diff --git a/interp/run.go b/interp/run.go index becd704f..dc978f03 100644 --- a/interp/run.go +++ b/interp/run.go @@ -415,7 +415,14 @@ func typeAssert(n *node, withResult, withOk bool) { } return next } - ok = canAssertTypes(v.value.Type(), rtype) + + styp := v.value.Type() + // TODO(mpl): probably also maps and others. and might have to recurse too. + if styp.String() == "[]interp.valueInterface" { + styp = v.node.typ.rtype + } + + ok = canAssertTypes(styp, rtype) if !ok { if !withOk { panic(fmt.Sprintf("interface conversion: interface {} is %s, not %s", v.value.Type().String(), rtype.String())) @@ -2153,7 +2160,11 @@ func arrayLit(n *node) { for i, v := range values { a.Index(index[i]).Set(v(f)) } - value(f).Set(a) + dest := value(f) + if _, ok := dest.Interface().(valueInterface); ok { + a = reflect.ValueOf(valueInterface{n, a}) + } + dest.Set(a) return next } }