fix: correct handling of interface types in composite literals

This commit is contained in:
Marc Vertes
2020-04-16 19:54:03 +02:00
committed by GitHub
parent 29e1777d82
commit c580dfdbc8
7 changed files with 88 additions and 13 deletions

11
_test/interface31.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
s := []interface{}{"test", 2}
fmt.Println(s[0], s[1])
}
// Output:
// test 2

11
_test/interface32.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
s := [2]interface{}{"test", 2}
fmt.Println(s[0], s[1])
}
// Output:
// test 2

11
_test/interface33.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
var a = map[string]interface{}{"test": "test"}
fmt.Println(a["test"])
}
// Output:
// test

11
_test/interface34.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import "fmt"
func main() {
s := [2]interface{}{1: "test", 0: 2}
fmt.Println(s[0], s[1])
}
// Output:
// 2 test

15
_test/interface35.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import "fmt"
type T struct {
I interface{}
}
func main() {
t := T{"test"}
fmt.Println(t)
}
// Output:
// {test}

View File

@@ -1580,11 +1580,19 @@ func arrayLit(n *node) {
for i, c := range child {
if c.kind == keyValueExpr {
convertLiteralValue(c.child[1], rtype)
values[i] = genValue(c.child[1])
if n.typ.val.cat == interfaceT {
values[i] = genValueInterface(c.child[1])
} else {
values[i] = genValue(c.child[1])
}
index[i] = int(vInt(c.child[0].rval))
} else {
convertLiteralValue(c, rtype)
values[i] = genValue(c)
if n.typ.val.cat == interfaceT {
values[i] = genValueInterface(c)
} else {
values[i] = genValue(c)
}
index[i] = prev
}
prev = index[i] + 1
@@ -1593,14 +1601,14 @@ func arrayLit(n *node) {
}
}
var a reflect.Value
if n.typ.sizedef {
a, _ = n.typ.zero()
} else {
a = reflect.MakeSlice(n.typ.TypeOf(), max, max)
}
typ := n.typ.frameType()
n.exec = func(f *frame) bltn {
var a reflect.Value
if n.typ.sizedef {
a, _ = n.typ.zero()
} else {
a = reflect.MakeSlice(typ, max, max)
}
for i, v := range values {
a.Index(index[i]).Set(v(f))
}
@@ -1622,8 +1630,16 @@ func mapLit(n *node) {
for i, c := range child {
convertLiteralValue(c.child[0], n.typ.key.TypeOf())
convertLiteralValue(c.child[1], n.typ.val.TypeOf())
keys[i] = genValue(c.child[0])
values[i] = genValue(c.child[1])
if n.typ.key.cat == interfaceT {
keys[i] = genValueInterface(c.child[0])
} else {
keys[i] = genValue(c.child[0])
}
if n.typ.val.cat == interfaceT {
values[i] = genValueInterface(c.child[1])
} else {
values[i] = genValue(c.child[1])
}
}
n.exec = func(f *frame) bltn {

View File

@@ -844,7 +844,7 @@ func (t *itype) zero() (v reflect.Value, err error) {
v, err = t.val.zero()
case arrayT, ptrT, structT:
v = reflect.New(t.TypeOf()).Elem()
v = reflect.New(t.frameType()).Elem()
case valueT:
v = reflect.New(t.rtype).Elem()
@@ -1002,7 +1002,7 @@ func exportName(s string) string {
return "X" + s
}
var interf = reflect.TypeOf(new(interface{})).Elem()
var interf = reflect.TypeOf((*interface{})(nil)).Elem()
// RefType returns a reflect.Type representation from an interpereter type.
// In simple cases, reflect types are directly mapped from the interpreter