From 387bb59ef6b54f2a4c9e02aef7afbcf20f87eb36 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 8 Jul 2021 12:06:29 +0200 Subject: [PATCH] interp: fix handling of interface value in forwarding return calls Special wrapping of interface value at return is no longer necessary and must be avoided now. Fixes #1179. --- _test/issue-1179.go | 23 +++++++++++++++++++++++ interp/run.go | 16 ++-------------- 2 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 _test/issue-1179.go diff --git a/_test/issue-1179.go b/_test/issue-1179.go new file mode 100644 index 000000000..b0b5580af --- /dev/null +++ b/_test/issue-1179.go @@ -0,0 +1,23 @@ +package main + +type I interface { + F() +} + +type T struct { + Name string +} + +func (t *T) F() { println("in F", t.Name) } + +func NewI(s string) I { return newT(s) } + +func newT(s string) *T { return &T{s} } + +func main() { + i := NewI("test") + i.F() +} + +// Output: +// in F test diff --git a/interp/run.go b/interp/run.go index aafea90aa..d05534829 100644 --- a/interp/run.go +++ b/interp/run.go @@ -1112,20 +1112,8 @@ func call(n *node) { // Function call from a return statement: forward return values (always at frame start). for i := range rtypes { j := n.findex + i - ret := n.child[0].typ.ret[i] - callret := n.anc.val.(*node).typ.ret[i] - - if isInterfaceSrc(callret) && !isEmptyInterface(callret) && !isInterfaceSrc(ret) { - // Wrap the returned value in a valueInterface in caller frame. - rvalues[i] = func(f *frame) reflect.Value { - v := reflect.New(ret.rtype).Elem() - f.data[j].Set(reflect.ValueOf(valueInterface{n, v})) - return v - } - } else { - // Set the return value location in return value of caller frame. - rvalues[i] = func(f *frame) reflect.Value { return f.data[j] } - } + // Set the return value location in return value of caller frame. + rvalues[i] = func(f *frame) reflect.Value { return f.data[j] } } default: // Multiple return values frame index are indexed from the node frame index.