From 2b1d6f0e7a453d18fec5c6043287f73010ba222f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 26 Mar 2021 09:34:03 +0100 Subject: [PATCH] interp: fix append on variadic recursive struct Fixes #1065. Improves #1058. --- _test/issue-1065.go | 20 ++++++++++++++++++++ interp/run.go | 2 +- interp/typecheck.go | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 _test/issue-1065.go diff --git a/_test/issue-1065.go b/_test/issue-1065.go new file mode 100644 index 000000000..e65a83f9a --- /dev/null +++ b/_test/issue-1065.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +type AST struct { + Num int + Children []AST +} + +func newAST(num int, root AST, children ...AST) AST { + return AST{num, append([]AST{root}, children...)} +} + +func main() { + ast := newAST(1, AST{}, AST{}) + fmt.Println(ast) +} + +// Output: +// {1 [{0 []} {0 []}]} diff --git a/interp/run.go b/interp/run.go index 0c006ba1a..24b71db53 100644 --- a/interp/run.go +++ b/interp/run.go @@ -2947,7 +2947,7 @@ func _append(n *node) { if len(n.child) == 3 { c1, c2 := n.child[1], n.child[2] if (c1.typ.cat == valueT || c2.typ.cat == valueT) && c1.typ.rtype == c2.typ.rtype || - c2.typ.cat == arrayT && c2.typ.val.id() == n.typ.val.id() || + (c2.typ.cat == arrayT || c2.typ.cat == variadicT) && c2.typ.val.id() == n.typ.val.id() || isByteArray(c1.typ.TypeOf()) && isString(c2.typ.TypeOf()) { appendSlice(n) return diff --git a/interp/typecheck.go b/interp/typecheck.go index b05080fb4..1fa7b0c76 100644 --- a/interp/typecheck.go +++ b/interp/typecheck.go @@ -48,6 +48,10 @@ func (check typecheck) assignment(n *node, typ *itype, context string) error { return nil } + if typ.isRecursive() || typ.val != nil && typ.val.isRecursive() { + return nil + } + if !n.typ.assignableTo(typ) { if context == "" { return n.cfgErrorf("cannot use type %s as type %s", n.typ.id(), typ.id())