Skip to content

Commit d6ad13a

Browse files
authored
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.
1 parent d124954 commit d6ad13a

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

_test/method40.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io"
6+
)
7+
8+
type TMemoryBuffer struct {
9+
*bytes.Buffer
10+
size int
11+
}
12+
13+
func newTMemoryBuffer() *TMemoryBuffer {
14+
return &TMemoryBuffer{}
15+
}
16+
17+
var globalMemoryBuffer = newTMemoryBuffer()
18+
19+
type TTransport interface {
20+
io.ReadWriter
21+
}
22+
23+
func check(t TTransport) {
24+
println("ok")
25+
}
26+
27+
func main() {
28+
check(globalMemoryBuffer)
29+
}
30+
31+
// Output:
32+
// ok

interp/type.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,8 +1544,11 @@ type methodSet map[string]string
15441544

15451545
// Contains returns true if the method set m contains the method set n.
15461546
func (m methodSet) contains(n methodSet) bool {
1547-
for k, v := range n {
1548-
if m[k] != v {
1547+
for k := range n {
1548+
// Only check the presence of method, not its complete signature,
1549+
// as the receiver may be part of the arguments, which makes a
1550+
// robust check complex.
1551+
if _, ok := m[k]; !ok {
15491552
return false
15501553
}
15511554
}
@@ -2132,8 +2135,14 @@ func (t *itype) refType(ctx *refTypeContext) reflect.Type {
21322135
var fields []reflect.StructField
21332136
for _, f := range t.field {
21342137
field := reflect.StructField{
2135-
Name: exportName(f.name), Type: f.typ.refType(ctx),
2136-
Tag: reflect.StructTag(f.tag), Anonymous: f.embed,
2138+
Name: exportName(f.name),
2139+
Type: f.typ.refType(ctx),
2140+
Tag: reflect.StructTag(f.tag),
2141+
}
2142+
if len(t.field) == 1 && f.embed {
2143+
// Mark the field as embedded (anonymous) only if it is the
2144+
// only one, to avoid a panic due to golang/go#15924 issue.
2145+
field.Anonymous = true
21372146
}
21382147
fields = append(fields, field)
21392148
// Find any nil type refs that indicates a rebuild is needed on this field.

0 commit comments

Comments
 (0)