Skip to content

Commit 6799a7a

Browse files
committed
internal/lsp/source: canonicalize objects in reference/rename requests
With generics, instantiated object may have differing pointer identities. Fix references/rename requests for instantiated methods/fields by using a canonical object identity of (pos, pkg, name). Fixes golang/go#51672 Change-Id: I0021ca562b8a74dadb616cf6864cb0bdd0165cc3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/392480 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 54a569a commit 6799a7a

File tree

8 files changed

+204
-5
lines changed

8 files changed

+204
-5
lines changed

internal/lsp/source/references.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,13 @@ func references(ctx context.Context, snapshot Snapshot, qos []qualifiedObject, i
109109
searchPkgs = append(searchPkgs, qo.pkg)
110110
for _, pkg := range searchPkgs {
111111
for ident, obj := range pkg.GetTypesInfo().Uses {
112-
if obj != qo.obj {
113-
// If ident is not a use of qo.obj, skip it, with one exception: uses
114-
// of an embedded field can be considered references of the embedded
115-
// type name.
112+
// For instantiated objects (as in methods or fields on instantiated
113+
// types), we may not have pointer-identical objects but still want to
114+
// consider them references.
115+
if !equalOrigin(obj, qo.obj) {
116+
// If ident is not a use of qo.obj, skip it, with one exception:
117+
// uses of an embedded field can be considered references of the
118+
// embedded type name
116119
if !includeEmbeddedRefs {
117120
continue
118121
}
@@ -167,6 +170,13 @@ func references(ctx context.Context, snapshot Snapshot, qos []qualifiedObject, i
167170
return references, nil
168171
}
169172

173+
// equalOrigin reports whether obj1 and obj2 have equivalent origin object.
174+
// This may be the case even if obj1 != obj2, if one or both of them is
175+
// instantiated.
176+
func equalOrigin(obj1, obj2 types.Object) bool {
177+
return obj1.Pkg() == obj2.Pkg() && obj1.Pos() == obj2.Pos() && obj1.Name() == obj2.Name()
178+
}
179+
170180
// interfaceReferences returns the references to the interfaces implemented by
171181
// the type or method at the given position.
172182
func interfaceReferences(ctx context.Context, s Snapshot, f FileHandle, pp protocol.Position) ([]*ReferenceInfo, error) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build go1.18
2+
// +build go1.18
3+
4+
package generics
5+
6+
type foo[P any] int //@rename("foo","bar")
7+
8+
var x struct{ foo[int] }
9+
10+
var _ = x.foo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- bar-rename --
2+
//go:build go1.18
3+
// +build go1.18
4+
5+
package generics
6+
7+
type bar[P any] int //@rename("foo","bar")
8+
9+
var x struct{ bar[int] }
10+
11+
var _ = x.bar
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//go:build go1.18
2+
// +build go1.18
3+
4+
package generics
5+
6+
type G[P any] struct {
7+
F int
8+
}
9+
10+
func (G[_]) M() {}
11+
12+
func F[P any](P) {
13+
var p P //@rename("P", "Q")
14+
_ = p
15+
}
16+
17+
func _() {
18+
var x G[int] //@rename("G", "H")
19+
_ = x.F //@rename("F", "K")
20+
x.M() //@rename("M", "N")
21+
22+
var y G[string]
23+
_ = y.F
24+
y.M()
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
-- Q-rename --
2+
//go:build go1.18
3+
// +build go1.18
4+
5+
package generics
6+
7+
type G[P any] struct {
8+
F int
9+
}
10+
11+
func (G[_]) M() {}
12+
13+
func F[Q any](Q) {
14+
var p Q //@rename("P", "Q")
15+
_ = p
16+
}
17+
18+
func _() {
19+
var x G[int] //@rename("G", "H")
20+
_ = x.F //@rename("F", "K")
21+
x.M() //@rename("M", "N")
22+
23+
var y G[string]
24+
_ = y.F
25+
y.M()
26+
}
27+
28+
-- H-rename --
29+
//go:build go1.18
30+
// +build go1.18
31+
32+
package generics
33+
34+
type H[P any] struct {
35+
F int
36+
}
37+
38+
func (H[_]) M() {}
39+
40+
func F[P any](P) {
41+
var p P //@rename("P", "Q")
42+
_ = p
43+
}
44+
45+
func _() {
46+
var x H[int] //@rename("G", "H")
47+
_ = x.F //@rename("F", "K")
48+
x.M() //@rename("M", "N")
49+
50+
var y H[string]
51+
_ = y.F
52+
y.M()
53+
}
54+
55+
-- K-rename --
56+
//go:build go1.18
57+
// +build go1.18
58+
59+
package generics
60+
61+
type G[P any] struct {
62+
K int
63+
}
64+
65+
func (G[_]) M() {}
66+
67+
func F[P any](P) {
68+
var p P //@rename("P", "Q")
69+
_ = p
70+
}
71+
72+
func _() {
73+
var x G[int] //@rename("G", "H")
74+
_ = x.K //@rename("F", "K")
75+
x.M() //@rename("M", "N")
76+
77+
var y G[string]
78+
_ = y.K
79+
y.M()
80+
}
81+
82+
-- N-rename --
83+
//go:build go1.18
84+
// +build go1.18
85+
86+
package generics
87+
88+
type G[P any] struct {
89+
F int
90+
}
91+
92+
func (G[_]) N() {}
93+
94+
func F[P any](P) {
95+
var p P //@rename("P", "Q")
96+
_ = p
97+
}
98+
99+
func _() {
100+
var x G[int] //@rename("G", "H")
101+
_ = x.F //@rename("F", "K")
102+
x.N() //@rename("M", "N")
103+
104+
var y G[string]
105+
_ = y.F
106+
y.N()
107+
}
108+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build go1.18
2+
// +build go1.18
3+
4+
package generics
5+
6+
type T string //@rename("T", "R")
7+
8+
type C interface {
9+
T | ~int //@rename("T", "S")
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- R-rename --
2+
//go:build go1.18
3+
// +build go1.18
4+
5+
package generics
6+
7+
type R string //@rename("T", "R")
8+
9+
type C interface {
10+
R | ~int //@rename("T", "S")
11+
}
12+
13+
-- S-rename --
14+
//go:build go1.18
15+
// +build go1.18
16+
17+
package generics
18+
19+
type S string //@rename("T", "R")
20+
21+
type C interface {
22+
S | ~int //@rename("T", "S")
23+
}
24+

internal/lsp/testdata/summary_go1.18.txt.golden

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ DefinitionsCount = 108
2020
TypeDefinitionsCount = 18
2121
HighlightsCount = 69
2222
ReferencesCount = 27
23-
RenamesCount = 41
23+
RenamesCount = 48
2424
PrepareRenamesCount = 7
2525
SymbolsCount = 5
2626
WorkspaceSymbolsCount = 20

0 commit comments

Comments
 (0)