// is shorthand for (&x).m()".
if f, _ := obj.(*Func); f != nil {
// determine if method has a pointer receiver
- hasPtrRecv := tpar == nil && ptrRecv(f)
+ hasPtrRecv := tpar == nil && f.hasPtrRecv()
if hasPtrRecv && !indirect && !addressable {
return nil, nil, true // pointer/addressable receiver required
}
// if f is not in the set, add it
if !multiples {
// TODO(gri) A found method may not be added because it's not in the method set
- // (!indirect && ptrRecv(f)). A 2nd method on the same level may be in the method
+ // (!indirect && f.hasPtrRecv()). A 2nd method on the same level may be in the method
// set and may not collide with the first one, thus leading to a false positive.
// Is that possible? Investigate.
- if _, found := s[key]; !found && (indirect || !ptrRecv(f)) {
+ if _, found := s[key]; !found && (indirect || !f.hasPtrRecv()) {
s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect}
continue
}
}
return s
}
-
-// ptrRecv reports whether the receiver is of the form *T.
-func ptrRecv(f *Func) bool {
- // If a method's receiver type is set, use that as the source of truth for the receiver.
- // Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
- // signature. We may reach here before the signature is fully set up: we must explicitly
- // check if the receiver is set (we cannot just look for non-nil f.typ).
- if sig, _ := f.typ.(*Signature); sig != nil && sig.recv != nil {
- _, isPtr := deref(sig.recv.typ)
- return isPtr
- }
-
- // If a method's type is not set it may be a method/function that is:
- // 1) client-supplied (via NewFunc with no signature), or
- // 2) internally created but not yet type-checked.
- // For case 1) we can't do anything; the client must know what they are doing.
- // For case 2) we can use the information gathered by the resolver.
- return f.hasPtrRecv
-}
// During type checking origm may not have a fully set up type, so defer
// instantiation of its signature until later.
m := NewFunc(origm.pos, origm.pkg, origm.name, nil)
- m.hasPtrRecv = ptrRecv(origm)
+ m.hasPtrRecv_ = origm.hasPtrRecv()
// Setting instRecv here allows us to complete later (we need the
// instRecv to get targs and the original method).
m.instRecv = n
sig = ©
}
var rtyp Type
- if ptrRecv(m) {
+ if m.hasPtrRecv() {
rtyp = NewPointer(rbase)
} else {
rtyp = rbase
// An abstract method may belong to many interfaces due to embedding.
type Func struct {
object
- instRecv *Named // if non-nil, the receiver type for an incomplete instance method
- hasPtrRecv bool // only valid for methods that don't have a type yet
+ instRecv *Named // if non-nil, the receiver type for an incomplete instance method
+ hasPtrRecv_ bool // only valid for methods that don't have a type yet; use hasPtrRecv() to read
}
// NewFunc returns a new function with the given signature, representing
// Scope returns the scope of the function's body block.
func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
+// hasPtrRecv reports whether the receiver is of the form *T for the given method obj.
+func (obj *Func) hasPtrRecv() bool {
+ // If a method's receiver type is set, use that as the source of truth for the receiver.
+ // Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
+ // signature. We may reach here before the signature is fully set up: we must explicitly
+ // check if the receiver is set (we cannot just look for non-nil obj.typ).
+ if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
+ _, isPtr := deref(sig.recv.typ)
+ return isPtr
+ }
+
+ // If a method's type is not set it may be a method/function that is:
+ // 1) client-supplied (via NewFunc with no signature), or
+ // 2) internally created but not yet type-checked.
+ // For case 1) we can't do anything; the client must know what they are doing.
+ // For case 2) we can use the information gathered by the resolver.
+ return obj.hasPtrRecv_
+}
+
func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
// A Label represents a declared label.
// Determine the receiver base type and associate m with it.
ptr, base := check.resolveBaseTypeName(m.ptr, m.recv)
if base != nil {
- m.obj.hasPtrRecv = ptr
+ m.obj.hasPtrRecv_ = ptr
check.methods[base] = append(check.methods[base], m.obj)
}
}