interp: enable type assertion from empty interface into slice

Fixes #985
This commit is contained in:
mpl
2020-12-15 17:28:04 +01:00
committed by GitHub
parent 9e1da978b0
commit 02c30482cc
2 changed files with 63 additions and 2 deletions

50
_test/composite15.go Normal file
View File

@@ -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

View File

@@ -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
}
}