Skip to content

Commit 9bdbed1

Browse files
committed
go/types, types2: complete methods on pointer receivers in missingMethod
We were not calling objDecl on methods on pointer receivers in missingMethod. This may not have mattered before, but with lazy completion of instance methods it is necessary. Fixes #49579 Change-Id: Icddb1f3b16bef7d8017859734f9879a4f1cc18de Reviewed-on: https://go-review.googlesource.com/c/go/+/364714 Trust: Robert Findley <[email protected]> Trust: Dan Scales <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 17b7604 commit 9bdbed1

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

src/cmd/compile/internal/types2/lookup.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
7171
// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
7272
// If checkFold is true, the lookup for methods will include looking for any method
7373
// which case-folds to the same as 'name' (used for giving helpful error messages).
74+
//
75+
// The resulting object may not be fully type-checked.
7476
func lookupFieldOrMethod(T Type, addressable, checkFold bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
7577
// WARNING: The code in this function is extremely subtle - do not modify casually!
7678

@@ -352,14 +354,17 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
352354
if obj == nil {
353355
ptr := NewPointer(V)
354356
obj, _, _ = lookupFieldOrMethod(ptr, false, false, m.pkg, m.name)
355-
if obj != nil {
356-
return m, obj.(*Func)
357+
if obj == nil {
358+
// If we didn't find the exact method (even with pointer
359+
// receiver), look to see if there is a method that
360+
// matches m.name with case-folding.
361+
obj, _, _ = lookupFieldOrMethod(V, false, true, m.pkg, m.name)
357362
}
358-
// If we didn't find the exact method (even with pointer
359-
// receiver), look to see if there is a method that
360-
// matches m.name with case-folding.
361-
obj, _, _ := lookupFieldOrMethod(V, false, true, m.pkg, m.name)
362363
if obj != nil {
364+
// methods may not have a fully set up signature yet
365+
if check != nil {
366+
check.objDecl(obj, nil)
367+
}
363368
return m, obj.(*Func)
364369
}
365370
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
type I[F any] interface {
8+
Q(*F)
9+
}
10+
11+
func G[F any]() I[any] {
12+
return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
13+
}
14+
15+
type g[F any] struct{}
16+
17+
func (*g[F]) Q(*any) {}

src/go/types/lookup.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
6969
// indirectly via different packages.)
7070

7171
// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
72+
//
73+
// The resulting object may not be fully type-checked.
7274
func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
7375
// WARNING: The code in this function is extremely subtle - do not modify casually!
7476

@@ -346,7 +348,12 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
346348
if obj == nil {
347349
ptr := NewPointer(V)
348350
obj, _, _ = lookupFieldOrMethod(ptr, false, m.pkg, m.name)
351+
349352
if obj != nil {
353+
// methods may not have a fully set up signature yet
354+
if check != nil {
355+
check.objDecl(obj, nil)
356+
}
350357
return m, obj.(*Func)
351358
}
352359
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
type I[F any] interface {
8+
Q(*F)
9+
}
10+
11+
func G[F any]() I[any] {
12+
return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
13+
}
14+
15+
type g[F any] struct{}
16+
17+
func (*g[F]) Q(*any) {}

0 commit comments

Comments
 (0)