internal/typeparams: delete OriginMethod

Use Func.Origin instead.

Change-Id: Ie4d29f2bd319a46901ce137107689e37d8e1edfa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/569316
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Tim King <taking@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
This commit is contained in:
Alan Donovan 2024-03-06 16:46:02 -05:00
Родитель 070fcfb90b
Коммит 9a6aed93ab
9 изменённых файлов: 17 добавлений и 79 удалений

Просмотреть файл

@ -8,8 +8,6 @@ import (
"fmt"
"go/types"
"sync"
"golang.org/x/tools/internal/typeparams"
)
// A generic records information about a generic origin function,
@ -80,7 +78,7 @@ func createInstance(fn *Function, targs []types.Type, cr *creator) *Function {
if prog.mode&InstantiateGenerics != 0 && !prog.parameterized.anyParameterized(targs) {
synthetic = fmt.Sprintf("instance of %s", fn.Name())
if fn.syntax != nil {
scope := typeparams.OriginMethod(obj).Scope()
scope := obj.Origin().Scope()
subst = makeSubster(prog.ctxt, scope, fn.typeparams, targs, false)
build = (*builder).buildFromSyntax
} else {

Просмотреть файл

@ -12,7 +12,6 @@ import (
"golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/typeparams"
)
// MethodValue returns the Function implementing method sel, building
@ -103,7 +102,7 @@ func (prog *Program) objectMethod(obj *types.Func, cr *creator) *Function {
}
// Instantiation of generic?
if originObj := typeparams.OriginMethod(obj); originObj != obj {
if originObj := obj.Origin(); originObj != obj {
origin := prog.objectMethod(originObj, cr)
assert(origin.typeparams.Len() > 0, "origin is not generic")
targs := receiverTypeArgs(obj)

Просмотреть файл

@ -14,8 +14,6 @@ import (
"go/ast"
"go/token"
"go/types"
"golang.org/x/tools/internal/typeparams"
)
// EnclosingFunction returns the function that contains the syntax
@ -122,7 +120,7 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function {
obj := mset.At(i).Obj().(*types.Func)
if obj.Pos() == pos {
// obj from MethodSet may not be the origin type.
m := typeparams.OriginMethod(obj)
m := obj.Origin()
return pkg.objects[m].(*Function)
}
}

Просмотреть файл

@ -30,7 +30,6 @@ import (
"strings"
"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
)
@ -395,7 +394,7 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
// of objectpath will only be giving us origin methods, anyway, as referring
// to instantiated methods is usually not useful.
if typeparams.OriginMethod(meth) != meth {
if meth.Origin() != meth {
return "", false
}

Просмотреть файл

@ -19,7 +19,6 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/analysisinternal"
"golang.org/x/tools/internal/typeparams"
)
//go:embed doc.go
@ -67,8 +66,8 @@ func checkDeprecated(pass *analysis.Pass) (interface{}, error) {
}
obj := pass.TypesInfo.ObjectOf(sel.Sel)
if obj_, ok := obj.(*types.Func); ok {
obj = typeparams.OriginMethod(obj_)
if fn, ok := obj.(*types.Func); ok {
obj = fn.Origin()
}
if obj == nil || obj.Pkg() == nil {
// skip invalid sel.Sel.

Просмотреть файл

@ -54,7 +54,6 @@ import (
"golang.org/x/tools/go/types/objectpath"
"golang.org/x/tools/gopls/internal/util/frob"
"golang.org/x/tools/gopls/internal/util/safetoken"
"golang.org/x/tools/internal/typeparams"
)
// An Index records the non-empty method sets of all package-level
@ -229,7 +228,7 @@ func (b *indexBuilder) build(fset *token.FileSet, pkg *types.Package) *Index {
// Instantiations of generic methods don't have an
// object path, so we use the generic.
if p, err := objectpathFor(typeparams.OriginMethod(method)); err != nil {
if p, err := objectpathFor(method.Origin()); err != nil {
panic(err) // can't happen for a method of a package-level type
} else {
m.ObjectPath = b.string(string(p))

3
gopls/internal/cache/xrefs/xrefs.go поставляемый
Просмотреть файл

@ -19,7 +19,6 @@ import (
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/util/frob"
"golang.org/x/tools/gopls/internal/util/typesutil"
"golang.org/x/tools/internal/typeparams"
)
// Index constructs a serializable index of outbound cross-references
@ -68,7 +67,7 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info) []byte {
// For instantiations of generic methods,
// use the generic object (see issue #60622).
if fn, ok := obj.(*types.Func); ok {
obj = typeparams.OriginMethod(fn)
obj = fn.Origin()
}
objects := getObjects(obj.Pkg())

Просмотреть файл

@ -13,13 +13,11 @@
package typeparams
import (
"fmt"
"go/ast"
"go/token"
"go/types"
"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/typesinternal"
)
// UnpackIndexExpr extracts data from AST nodes that represent index
@ -71,57 +69,6 @@ func IsTypeParam(t types.Type) bool {
return ok
}
// OriginMethod returns the origin method associated with the method fn.
// For methods on a non-generic receiver base type, this is just
// fn. However, for methods with a generic receiver, OriginMethod returns the
// corresponding method in the method set of the origin type.
//
// As a special case, if fn is not a method (has no receiver), OriginMethod
// returns fn.
func OriginMethod(fn *types.Func) *types.Func {
recv := fn.Type().(*types.Signature).Recv()
if recv == nil {
return fn
}
_, named := typesinternal.ReceiverNamed(recv)
if named == nil {
// Receiver is a *types.Interface.
return fn
}
if named.TypeParams().Len() == 0 {
// Receiver base has no type parameters, so we can avoid the lookup below.
return fn
}
orig := named.Origin()
gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
// This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In:
// package p
// type T *int
// func (*T) f() {}
// LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}.
// Here we make them consistent by force.
// (The go/types bug is general, but this workaround is reached only
// for generic T thanks to the early return above.)
if gfn == nil {
mset := types.NewMethodSet(types.NewPointer(orig))
for i := 0; i < mset.Len(); i++ {
m := mset.At(i)
if m.Obj().Id() == fn.Id() {
gfn = m.Obj()
break
}
}
}
// In golang/go#61196, we observe another crash, this time inexplicable.
if gfn == nil {
panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods()))
}
return gfn.(*types.Func)
}
// GenericAssignableTo is a generalization of types.AssignableTo that
// implements the following rule for uninstantiated generic types:
//

Просмотреть файл

@ -39,7 +39,7 @@ func TestGetIndexExprData(t *testing.T) {
}
}
func TestOriginMethodRecursive(t *testing.T) {
func TestFuncOriginRecursive(t *testing.T) {
src := `package p
type N[A any] int
@ -104,13 +104,13 @@ func (r *N[C]) n() { }
}
for _, test := range tests {
if got := OriginMethod(test.input); got != test.want {
t.Errorf("OriginMethod(%q) = %v, want %v", test.name, test.input, test.want)
if got := test.input.Origin(); got != test.want {
t.Errorf("Origin(%q) = %v, want %v", test.name, test.input, test.want)
}
}
}
func TestOriginMethodUses(t *testing.T) {
func TestFuncOriginUses(t *testing.T) {
tests := []string{
`type T interface { m() }; func _(t T) { t.m() }`,
@ -147,7 +147,7 @@ func TestOriginMethodUses(t *testing.T) {
if call, ok := n.(*ast.CallExpr); ok {
sel := call.Fun.(*ast.SelectorExpr)
use := info.Uses[sel.Sel].(*types.Func)
orig := OriginMethod(use)
orig := use.Origin()
if orig != m {
t.Errorf("%s:\nUses[%v] = %v, want %v", src, types.ExprString(sel), use, m)
}
@ -160,8 +160,8 @@ func TestOriginMethodUses(t *testing.T) {
// Issue #60628 was a crash in gopls caused by inconsistency (#60634) between
// LookupFieldOrMethod and NewFileSet for methods with an illegal
// *T receiver type, where T itself is a pointer.
// This is a regression test for the workaround in OriginMethod.
func TestOriginMethod60628(t *testing.T) {
// This is a regression test for the workaround in the (now deleted) OriginMethod.
func TestFuncOrigin60628(t *testing.T) {
const src = `package p; type T[P any] *int; func (r *T[A]) f() {}`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "p.go", src, 0)
@ -199,8 +199,8 @@ func TestOriginMethod60628(t *testing.T) {
}
// Check the workaround.
if OriginMethod(m) == nil {
t.Errorf("OriginMethod(%v) = nil", m)
if m.Origin() == nil {
t.Errorf("Origin(%v) = nil", m)
}
}
}