Skip to content

Commit

Permalink
interp: improve handling of embedded fields with binary methods
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mvertes authored Apr 13, 2023
1 parent d124954 commit d6ad13a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
32 changes: 32 additions & 0 deletions _test/method40.go
Original file line number Diff line number Diff line change
@@ -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
17 changes: 13 additions & 4 deletions interp/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1544,8 +1544,11 @@ type methodSet map[string]string

// Contains returns true if the method set m contains the method set n.
func (m methodSet) contains(n methodSet) bool {
for k, v := range n {
if m[k] != v {
for k := range n {
// 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
}
}
Expand Down Expand Up @@ -2132,8 +2135,14 @@ func (t *itype) refType(ctx *refTypeContext) reflect.Type {
var fields []reflect.StructField
for _, f := range t.field {
field := reflect.StructField{
Name: exportName(f.name), Type: f.typ.refType(ctx),
Tag: reflect.StructTag(f.tag), Anonymous: f.embed,
Name: exportName(f.name),
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)
// Find any nil type refs that indicates a rebuild is needed on this field.
Expand Down

0 comments on commit d6ad13a

Please sign in to comment.