From ca196a5768fa0e7044dace80375e80100df93925 Mon Sep 17 00:00:00 2001 From: mpl Date: Mon, 5 Oct 2020 16:42:03 +0200 Subject: [PATCH] interp: fix implicit type for bin composite lit case When the type is implicit, the first element in the list of children is not the type of the composite literal, but it is one of the actual children, so it should not be discarded. Fixes #862 --- _test/binstruct_slice0.go | 16 ++++++++++++++++ interp/cfg.go | 8 ++++++-- interp/run.go | 12 +++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 _test/binstruct_slice0.go diff --git a/_test/binstruct_slice0.go b/_test/binstruct_slice0.go new file mode 100644 index 00000000..211f60fa --- /dev/null +++ b/_test/binstruct_slice0.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "image" +) + +func main() { + v := []image.Point{ + {X: 3, Y: 2}, + } + fmt.Println(v) +} + +// Output: +// [(3,2)] diff --git a/interp/cfg.go b/interp/cfg.go index a918d0ed..100bab6e 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -1129,7 +1129,6 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) { sym, level, found := sc.lookup(n.ident) if !found { // retry with the filename, in case ident is a package name. - // TODO(mpl): maybe we improve lookup itself so it can deal with that. sym, level, found = sc.lookup(filepath.Join(n.ident, baseName)) if !found { err = n.cfgErrorf("undefined: %s", n.ident) @@ -2388,8 +2387,13 @@ func compositeGenerator(n *node, typ *itype) (gen bltnGenerator) { case valueT: switch k := n.typ.rtype.Kind(); k { case reflect.Struct: - gen = compositeBinStruct + if n.nleft == 1 { + gen = compositeBinStruct + } else { + gen = compositeBinStructNotype + } case reflect.Map: + // TODO(mpl): maybe needs a NoType VS Type too gen = compositeBinMap default: log.Panic(n.cfgErrorf("compositeGenerator not implemented for type kind: %s", k)) diff --git a/interp/run.go b/interp/run.go index 058d89d3..b1c5ad33 100644 --- a/interp/run.go +++ b/interp/run.go @@ -2010,12 +2010,15 @@ func compositeBinMap(n *node) { } } -// compositeBinStruct creates and populates a struct object from a binary type. -func compositeBinStruct(n *node) { +// doCompositeBinStruct creates and populates a struct object from a binary type. +func doCompositeBinStruct(n *node, hasType bool) { next := getExec(n.tnext) value := valueGenerator(n, n.findex) typ := n.typ.rtype - child := n.child[1:] + child := n.child + if hasType { + child = n.child[1:] + } values := make([]func(*frame) reflect.Value, len(child)) fieldIndex := make([][]int, len(child)) for i, c := range child { @@ -2051,6 +2054,9 @@ func compositeBinStruct(n *node) { } } +func compositeBinStruct(n *node) { doCompositeBinStruct(n, true) } +func compositeBinStructNotype(n *node) { doCompositeBinStruct(n, false) } + func destType(n *node) *itype { switch n.anc.kind { case assignStmt, defineStmt: