Skip to content

Commit

Permalink
fix: correct handling of interface types in composite literals
Browse files Browse the repository at this point in the history
  • Loading branch information
mvertes committed Apr 16, 2020
1 parent 29e1777 commit c580dfd
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 13 deletions.
11 changes: 11 additions & 0 deletions _test/interface31.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import "fmt"

func main() {
s := []interface{}{"test", 2}
fmt.Println(s[0], s[1])
}

// Output:
// test 2
11 changes: 11 additions & 0 deletions _test/interface32.go
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions _test/interface33.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import "fmt"

func main() {
var a = map[string]interface{}{"test": "test"}
fmt.Println(a["test"])
}

// Output:
// test
11 changes: 11 additions & 0 deletions _test/interface34.go
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions _test/interface35.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import "fmt"

type T struct {
I interface{}
}

func main() {
t := T{"test"}
fmt.Println(t)
}

// Output:
// {test}
38 changes: 27 additions & 11 deletions interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
}
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions interp/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c580dfd

Please sign in to comment.