// TODO(rfindley) confirm that this code is in sync with lookupFieldOrMethod
// with respect to type params.
+ // Methods cannot be associated with a named pointer type.
+ // (spec: "The type denoted by T is called the receiver base type;
+ // it must not be a pointer or interface type and it must be declared
+ // in the same package as the method.").
+ if t, _ := T.(*Named); t != nil && isPointer(t) {
+ return &emptyMethodSet
+ }
+
// method set up to the current depth, allocated lazily
var base methodSet
package types_test
import (
+ "strings"
"testing"
"go/ast"
T := pkg.Scope().Lookup("Instance").Type()
_ = NewMethodSet(T) // verify that NewMethodSet terminates
}
+
+func TestIssue60634(t *testing.T) {
+ const src = `
+package p
+type T *int
+func (T) m() {} // expected error: invalid receiver type
+`
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "p.go", src, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var conf Config
+ pkg, err := conf.Check("p", fset, []*ast.File{f}, nil)
+ if err == nil || !strings.Contains(err.Error(), "invalid receiver type") {
+ t.Fatalf("missing or unexpected error: %v", err)
+ }
+
+ // look up T.m and (*T).m
+ T := pkg.Scope().Lookup("T").Type()
+ name := "m"
+ for _, recv := range []Type{T, NewPointer(T)} {
+ // LookupFieldOrMethod and NewMethodSet must match:
+ // either both find m or neither finds it.
+ obj1, _, _ := LookupFieldOrMethod(recv, false, pkg, name)
+ mset := NewMethodSet(recv)
+ if (obj1 != nil) != (mset.Len() == 1) {
+ t.Fatalf("lookup(%v.%s): got obj = %v, mset = %v", recv, name, obj1, mset)
+ }
+ // If the method exists, both must return the same object.
+ if obj1 != nil {
+ obj2 := mset.At(0).Obj()
+ if obj1 != obj2 {
+ t.Fatalf("%v != %v", obj1, obj2)
+ }
+ }
+ }
+}