diff --git a/_test/fun19.go b/_test/fun19.go new file mode 100644 index 00000000..beb61bbb --- /dev/null +++ b/_test/fun19.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" +) + +func foo() ([]string, error) { + return nil, fmt.Errorf("bar") +} + +func main() { + a, b := foo() + fmt.Println(a, b) +} + +// Output: +// [] bar diff --git a/_test/fun20.go b/_test/fun20.go new file mode 100644 index 00000000..29c7c204 --- /dev/null +++ b/_test/fun20.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +var myerr error = fmt.Errorf("bar") + +func ferr() error { return myerr } + +func foo() ([]string, error) { + return nil, ferr() +} + +func main() { + a, b := foo() + fmt.Println(a, b) +} + +// Output: +// [] bar diff --git a/interp/cfg.go b/interp/cfg.go index 7ab74774..766005e8 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -823,9 +823,13 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) { } } else { n.typ = &itype{cat: valueT, rtype: typ.Out(0)} - n.findex = sc.add(n.typ) - for i := 1; i < typ.NumOut(); i++ { - sc.add(&itype{cat: valueT, rtype: typ.Out(i)}) + if n.anc.kind == returnStmt { + n.findex = childPos(n) + } else { + n.findex = sc.add(n.typ) + for i := 1; i < typ.NumOut(); i++ { + sc.add(&itype{cat: valueT, rtype: typ.Out(i)}) + } } } } @@ -836,9 +840,13 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) { } if typ := n.child[0].typ; len(typ.ret) > 0 { n.typ = typ.ret[0] - n.findex = sc.add(n.typ) - for _, t := range typ.ret[1:] { - sc.add(t) + if n.anc.kind == returnStmt { + n.findex = childPos(n) + } else { + n.findex = sc.add(n.typ) + for _, t := range typ.ret[1:] { + sc.add(t) + } } } else { n.findex = -1 diff --git a/interp/run.go b/interp/run.go index 02363d99..74bed298 100644 --- a/interp/run.go +++ b/interp/run.go @@ -687,7 +687,7 @@ func call(n *node) { case returnStmt: // Function call from a return statement: forward return values (always at frame start). for i := range rtypes { - j := i + j := n.findex + i ret := n.child[0].typ.ret[i] callret := n.anc.val.(*node).typ.ret[i] if callret.cat == interfaceT && ret.cat != interfaceT { @@ -983,6 +983,7 @@ func callBin(n *node) { case aReturn: // The function call is part of a return statement, store output results // directly in the frame location of outputs of the current function. + b := childPos(n) n.exec = func(f *frame) bltn { in := make([]reflect.Value, l) for i, v := range values { @@ -990,7 +991,7 @@ func callBin(n *node) { } out := value(f).Call(in) for i, v := range out { - f.data[i].Set(v) + f.data[b+i].Set(v) } return tnext }