mirror of https://github.com/golang/go.git
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 <rfindley@google.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
17b7604ef6
commit
9bdbed1d96
|
|
@ -71,6 +71,8 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
|
|||
// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
|
||||
// If checkFold is true, the lookup for methods will include looking for any method
|
||||
// which case-folds to the same as 'name' (used for giving helpful error messages).
|
||||
//
|
||||
// The resulting object may not be fully type-checked.
|
||||
func lookupFieldOrMethod(T Type, addressable, checkFold bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
|
||||
// WARNING: The code in this function is extremely subtle - do not modify casually!
|
||||
|
||||
|
|
@ -352,14 +354,17 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
|
|||
if obj == nil {
|
||||
ptr := NewPointer(V)
|
||||
obj, _, _ = lookupFieldOrMethod(ptr, false, false, m.pkg, m.name)
|
||||
if obj != nil {
|
||||
return m, obj.(*Func)
|
||||
if obj == nil {
|
||||
// If we didn't find the exact method (even with pointer
|
||||
// receiver), look to see if there is a method that
|
||||
// matches m.name with case-folding.
|
||||
obj, _, _ = lookupFieldOrMethod(V, false, true, m.pkg, m.name)
|
||||
}
|
||||
// If we didn't find the exact method (even with pointer
|
||||
// receiver), look to see if there is a method that
|
||||
// matches m.name with case-folding.
|
||||
obj, _, _ := lookupFieldOrMethod(V, false, true, m.pkg, m.name)
|
||||
if obj != nil {
|
||||
// methods may not have a fully set up signature yet
|
||||
if check != nil {
|
||||
check.objDecl(obj, nil)
|
||||
}
|
||||
return m, obj.(*Func)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
type I[F any] interface {
|
||||
Q(*F)
|
||||
}
|
||||
|
||||
func G[F any]() I[any] {
|
||||
return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
|
||||
}
|
||||
|
||||
type g[F any] struct{}
|
||||
|
||||
func (*g[F]) Q(*any) {}
|
||||
|
|
@ -69,6 +69,8 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
|
|||
// indirectly via different packages.)
|
||||
|
||||
// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
|
||||
//
|
||||
// The resulting object may not be fully type-checked.
|
||||
func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
|
||||
// WARNING: The code in this function is extremely subtle - do not modify casually!
|
||||
|
||||
|
|
@ -346,7 +348,12 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
|
|||
if obj == nil {
|
||||
ptr := NewPointer(V)
|
||||
obj, _, _ = lookupFieldOrMethod(ptr, false, m.pkg, m.name)
|
||||
|
||||
if obj != nil {
|
||||
// methods may not have a fully set up signature yet
|
||||
if check != nil {
|
||||
check.objDecl(obj, nil)
|
||||
}
|
||||
return m, obj.(*Func)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
type I[F any] interface {
|
||||
Q(*F)
|
||||
}
|
||||
|
||||
func G[F any]() I[any] {
|
||||
return g /* ERROR "missing method Q \(Q has pointer receiver\)" */ [F]{}
|
||||
}
|
||||
|
||||
type g[F any] struct{}
|
||||
|
||||
func (*g[F]) Q(*any) {}
|
||||
Loading…
Reference in New Issue