interp: fix interface wrapper generation

Add early detection of cases where no wrapper is necessary because
the value type already implements the target interface.

It should both increase performances by avoiding the wrapper overhead,
and fix errors due to replacing valid values by incomplete wrappers,
caused by the presence of private methods in the interface definition,
as in #1191.

Fixes #1191.
This commit is contained in:
Marc Vertes
2021-07-19 15:38:11 +02:00
committed by GitHub
parent aa012b992e
commit c7fcfa8534
2 changed files with 22 additions and 1 deletions

17
_test/interface52.go Normal file
View File

@@ -0,0 +1,17 @@
package main
import "testing"
func main() {
t := testing.T{}
var tb testing.TB
tb = &t
if tb.TempDir() == "" {
println("FAIL")
return
}
println("PASS")
}
// Output:
// PASS

View File

@@ -971,7 +971,8 @@ func genInterfaceWrapper(n *node, typ reflect.Type) func(*frame) reflect.Value {
if typ == nil || typ.Kind() != reflect.Interface || typ.NumMethod() == 0 || n.typ.cat == valueT {
return value
}
if nt := n.typ.TypeOf(); nt != nil && nt.Kind() == reflect.Interface {
nt := n.typ.frameType()
if nt != nil && nt.Implements(typ) {
return value
}
mn := typ.NumMethod()
@@ -990,6 +991,9 @@ func genInterfaceWrapper(n *node, typ reflect.Type) func(*frame) reflect.Value {
return func(f *frame) reflect.Value {
v := value(f)
if v.Type().Implements(typ) {
return v
}
vv := v
switch v.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: