fix: resolve receiver for binary methods on non interface types
This commit is contained in:
21
_test/struct36.go
Normal file
21
_test/struct36.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type S struct {
|
||||
http.Client
|
||||
}
|
||||
|
||||
func main() {
|
||||
var s S
|
||||
if _, err := s.Get("url"); err != nil {
|
||||
println(strings.Contains(err.Error(), "unsupported protocol scheme"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Output:
|
||||
// true
|
||||
@@ -1219,6 +1219,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
|
||||
} else {
|
||||
n.gen = getIndexSeqMethod
|
||||
}
|
||||
n.recv = &receiver{node: n.child[0], index: lind}
|
||||
n.val = append([]int{m.Index}, lind...)
|
||||
n.typ = &itype{cat: valueT, rtype: m.Type}
|
||||
} else if ti := n.typ.lookupField(n.child[1].ident); len(ti) > 0 {
|
||||
|
||||
@@ -803,7 +803,7 @@ func pindex(i, variadic int) int {
|
||||
return variadic
|
||||
}
|
||||
|
||||
// Call a function from a bin import, accessible through reflect
|
||||
// Callbin calls a function from a bin import, accessible through reflect.
|
||||
func callBin(n *node) {
|
||||
tnext := getExec(n.tnext)
|
||||
fnext := getExec(n.fnext)
|
||||
@@ -815,9 +815,9 @@ func callBin(n *node) {
|
||||
if funcType.IsVariadic() {
|
||||
variadic = funcType.NumIn() - 1
|
||||
}
|
||||
// method signature obtained from reflect.Type include receiver as 1st arg, except for interface types
|
||||
// A method signature obtained from reflect.Type includes receiver as 1st arg, except for interface types.
|
||||
rcvrOffset := 0
|
||||
if recv := n.child[0].recv; recv != nil && recv.node.typ.TypeOf().Kind() != reflect.Interface {
|
||||
if recv := n.child[0].recv; recv != nil && !isInterface(recv.node.typ) {
|
||||
if funcType.NumIn() > len(child) {
|
||||
rcvrOffset = 1
|
||||
}
|
||||
|
||||
@@ -871,13 +871,11 @@ func (t *itype) lookupMethod(name string) (*node, []int) {
|
||||
}
|
||||
|
||||
// lookupBinMethod returns a method and a path to access a field in a struct object (the receiver)
|
||||
func (t *itype) lookupBinMethod(name string) (reflect.Method, []int, bool, bool) {
|
||||
var isPtr bool
|
||||
func (t *itype) lookupBinMethod(name string) (m reflect.Method, index []int, isPtr bool, ok bool) {
|
||||
if t.cat == ptrT {
|
||||
return t.val.lookupBinMethod(name)
|
||||
}
|
||||
var index []int
|
||||
m, ok := t.TypeOf().MethodByName(name)
|
||||
m, ok = t.TypeOf().MethodByName(name)
|
||||
if !ok {
|
||||
m, ok = reflect.PtrTo(t.TypeOf()).MethodByName(name)
|
||||
isPtr = ok
|
||||
|
||||
Reference in New Issue
Block a user