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:
32
_test/method40.go
Normal file
32
_test/method40.go
Normal 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
|
||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user