Skip to content

Commit

Permalink
interp: fix handling of interface value in forwarding return calls
Browse files Browse the repository at this point in the history
Special wrapping of interface value at return is no longer necessary and
must be avoided now.

Fixes #1179.
  • Loading branch information
mvertes authored and traefiker committed Jul 8, 2021
1 parent 77acfb4 commit 387bb59
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
23 changes: 23 additions & 0 deletions _test/issue-1179.go
Original file line number Diff line number Diff line change
@@ -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
16 changes: 2 additions & 14 deletions interp/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 387bb59

Please sign in to comment.