interp: improve handling of embedded fields with binary methods

Only structures with one embedded field can be marked anonymous, due to golang/go#15924. Also check only that the method is defined, do not verify its complete signature, as the receiver may or not be defined in the arguments of the method.

Fixes #1537.
This commit is contained in:
Marc Vertes
2023-04-13 18:16:05 +02:00
committed by GitHub
parent d124954a7d
commit d6ad13acea
2 changed files with 45 additions and 4 deletions

32
_test/method40.go Normal file
View File

@@ -0,0 +1,32 @@
package main
import (
"bytes"
"io"
)
type TMemoryBuffer struct {
*bytes.Buffer
size int
}
func newTMemoryBuffer() *TMemoryBuffer {
return &TMemoryBuffer{}
}
var globalMemoryBuffer = newTMemoryBuffer()
type TTransport interface {
io.ReadWriter
}
func check(t TTransport) {
println("ok")
}
func main() {
check(globalMemoryBuffer)
}
// Output:
// ok

View File

@@ -1544,8 +1544,11 @@ type methodSet map[string]string
// Contains returns true if the method set m contains the method set n. // Contains returns true if the method set m contains the method set n.
func (m methodSet) contains(n methodSet) bool { func (m methodSet) contains(n methodSet) bool {
for k, v := range n { for k := range n {
if m[k] != v { // Only check the presence of method, not its complete signature,
// as the receiver may be part of the arguments, which makes a
// robust check complex.
if _, ok := m[k]; !ok {
return false return false
} }
} }
@@ -2132,8 +2135,14 @@ func (t *itype) refType(ctx *refTypeContext) reflect.Type {
var fields []reflect.StructField var fields []reflect.StructField
for _, f := range t.field { for _, f := range t.field {
field := reflect.StructField{ field := reflect.StructField{
Name: exportName(f.name), Type: f.typ.refType(ctx), Name: exportName(f.name),
Tag: reflect.StructTag(f.tag), Anonymous: f.embed, Type: f.typ.refType(ctx),
Tag: reflect.StructTag(f.tag),
}
if len(t.field) == 1 && f.embed {
// Mark the field as embedded (anonymous) only if it is the
// only one, to avoid a panic due to golang/go#15924 issue.
field.Anonymous = true
} }
fields = append(fields, field) fields = append(fields, field)
// Find any nil type refs that indicates a rebuild is needed on this field. // Find any nil type refs that indicates a rebuild is needed on this field.