@@ -140,10 +140,12 @@ func TestOriginMethodUses(t *testing.T) {
140
140
t .Fatal (err )
141
141
}
142
142
143
+ // Look up func T.m.
143
144
T := pkg .Scope ().Lookup ("T" ).Type ()
144
145
obj , _ , _ := types .LookupFieldOrMethod (T , true , pkg , "m" )
145
146
m := obj .(* types.Func )
146
147
148
+ // Assert that the origin of each t.m() call is p.T.m.
147
149
ast .Inspect (f , func (n ast.Node ) bool {
148
150
if call , ok := n .(* ast.CallExpr ); ok {
149
151
sel := call .Fun .(* ast.SelectorExpr )
@@ -158,6 +160,54 @@ func TestOriginMethodUses(t *testing.T) {
158
160
}
159
161
}
160
162
163
+ // Issue #60628 was a crash in gopls caused by inconsistency (#60634) between
164
+ // LookupFieldOrMethod and NewFileSet for methods with an illegal
165
+ // *T receiver type, where T itself is a pointer.
166
+ // This is a regression test for the workaround in OriginMethod.
167
+ func TestOriginMethod60628 (t * testing.T ) {
168
+ const src = `package p; type T[P any] *int; func (r *T[A]) f() {}`
169
+ fset := token .NewFileSet ()
170
+ f , err := parser .ParseFile (fset , "p.go" , src , 0 )
171
+ if err != nil {
172
+ t .Fatal (err )
173
+ }
174
+
175
+ // Expect type error: "invalid receiver type T[A] (pointer or interface type)".
176
+ info := types.Info {
177
+ Uses : make (map [* ast.Ident ]types.Object ),
178
+ }
179
+ var conf types.Config
180
+ pkg , _ := conf .Check ("p" , fset , []* ast.File {f }, & info ) // error expected
181
+ if pkg == nil {
182
+ t .Fatal ("no package" )
183
+ }
184
+
185
+ // Look up methodset of *T.
186
+ T := pkg .Scope ().Lookup ("T" ).Type ()
187
+ mset := types .NewMethodSet (types .NewPointer (T ))
188
+ if mset .Len () == 0 {
189
+ t .Errorf ("NewMethodSet(*T) is empty" )
190
+ }
191
+ for i := 0 ; i < mset .Len (); i ++ {
192
+ sel := mset .At (i )
193
+ m := sel .Obj ().(* types.Func )
194
+
195
+ // TODO(adonovan): check the consistency property required to fix #60634.
196
+ if false {
197
+ m2 , _ , _ := types .LookupFieldOrMethod (T , true , m .Pkg (), m .Name ())
198
+ if m2 != m {
199
+ t .Errorf ("LookupFieldOrMethod(%v, indirect=true, %v) = %v, want %v" ,
200
+ T , m , m2 , m )
201
+ }
202
+ }
203
+
204
+ // Check the workaround.
205
+ if OriginMethod (m ) == nil {
206
+ t .Errorf ("OriginMethod(%v) = nil" , m )
207
+ }
208
+ }
209
+ }
210
+
161
211
func TestGenericAssignableTo (t * testing.T ) {
162
212
testenv .NeedsGo1Point (t , 18 )
163
213
0 commit comments