Skip to content

Commit

Permalink
interp: support implicit-type slice of pointers of struct composite l…
Browse files Browse the repository at this point in the history
…iteral

Also fix same case for implicit-type maps of etc.

Fixes #883
  • Loading branch information
mpl authored Oct 9, 2020
1 parent ca196a5 commit 155ca4e
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
17 changes: 17 additions & 0 deletions _test/binstruct_ptr_map0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
"fmt"
"image"
)

func main() {
v := map[string]*image.Point{
"foo": {X: 3, Y: 2},
"bar": {X: 4, Y: 5},
}
fmt.Println(v["foo"], v["bar"])
}

// Output:
// (3,2) (4,5)
17 changes: 17 additions & 0 deletions _test/binstruct_ptr_slice0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
"fmt"
"image"
)

func main() {
v := []*image.Point{
{X: 3, Y: 2},
{X: 4, Y: 5},
}
fmt.Println(v)
}

// Output:
// [(3,2) (4,5)]
15 changes: 10 additions & 5 deletions interp/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {

n.findex = sc.add(n.typ)
// TODO: Check that composite literal expr matches corresponding type
n.gen = compositeGenerator(n, n.typ)
n.gen = compositeGenerator(n, n.typ, nil)

case fallthroughtStmt:
if n.anc.kind != caseBody {
Expand Down Expand Up @@ -2359,10 +2359,10 @@ func gotoLabel(s *symbol) {
}
}

func compositeGenerator(n *node, typ *itype) (gen bltnGenerator) {
func compositeGenerator(n *node, typ *itype, rtyp reflect.Type) (gen bltnGenerator) {
switch typ.cat {
case aliasT, ptrT:
gen = compositeGenerator(n, n.typ.val)
gen = compositeGenerator(n, n.typ.val, rtyp)
case arrayT:
gen = arrayLit
case mapT:
Expand All @@ -2385,16 +2385,21 @@ func compositeGenerator(n *node, typ *itype) (gen bltnGenerator) {
}
}
case valueT:
switch k := n.typ.rtype.Kind(); k {
if rtyp == nil {
rtyp = n.typ.rtype
}
switch k := rtyp.Kind(); k {
case reflect.Struct:
if n.nleft == 1 {
gen = compositeBinStruct
} else {
gen = compositeBinStructNotype
}
case reflect.Map:
// TODO(mpl): maybe needs a NoType VS Type too
// TODO(mpl): maybe needs a NoType version too
gen = compositeBinMap
case reflect.Ptr:
gen = compositeGenerator(n, typ, n.typ.val.rtype)
default:
log.Panic(n.cfgErrorf("compositeGenerator not implemented for type kind: %s", k))
}
Expand Down
11 changes: 10 additions & 1 deletion interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,9 @@ func doCompositeBinStruct(n *node, hasType bool) {
next := getExec(n.tnext)
value := valueGenerator(n, n.findex)
typ := n.typ.rtype
if n.typ.cat == ptrT || n.typ.cat == aliasT {
typ = n.typ.val.rtype
}
child := n.child
if hasType {
child = n.child[1:]
Expand Down Expand Up @@ -2049,7 +2052,13 @@ func doCompositeBinStruct(n *node, hasType bool) {
for i, v := range values {
s.FieldByIndex(fieldIndex[i]).Set(v(f))
}
value(f).Set(s)
d := value(f)
switch {
case d.Type().Kind() == reflect.Ptr:
d.Set(s.Addr())
default:
d.Set(s)
}
return next
}
}
Expand Down

0 comments on commit 155ca4e

Please sign in to comment.