Skip to content

Commit 82861e0

Browse files
committed
gopls/internal/lsp/source: reinstate equalOrigin for references check
This logic was dropped in CL 464902, but is necessary for correctly resolving references to variables. Fixes golang/go#61618 Change-Id: Iebe46339e5f6ac0230f7376e742d786bae2a7438 Reviewed-on: https://go-review.googlesource.com/c/tools/+/513780 Run-TryBot: Robert Findley <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
1 parent 1561060 commit 82861e0

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

gopls/internal/lsp/source/references.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -580,9 +580,12 @@ func localReferences(pkg Package, targets map[types.Object]bool, correspond bool
580580
// matches reports whether obj either is or corresponds to a target.
581581
// (Correspondence is defined as usual for interface methods.)
582582
matches := func(obj types.Object) bool {
583-
if targets[obj] {
584-
return true
585-
} else if methodRecvs != nil && obj.Name() == methodName {
583+
for target := range targets {
584+
if equalOrigin(obj, target) {
585+
return true
586+
}
587+
}
588+
if methodRecvs != nil && obj.Name() == methodName {
586589
if orecv := effectiveReceiver(obj); orecv != nil {
587590
for _, mrecv := range methodRecvs {
588591
if concreteImplementsIntf(orecv, mrecv) {
@@ -608,6 +611,13 @@ func localReferences(pkg Package, targets map[types.Object]bool, correspond bool
608611
return nil
609612
}
610613

614+
// equalOrigin reports whether obj1 and obj2 have equivalent origin object.
615+
// This may be the case even if obj1 != obj2, if one or both of them is
616+
// instantiated.
617+
func equalOrigin(obj1, obj2 types.Object) bool {
618+
return obj1.Pkg() == obj2.Pkg() && obj1.Pos() == obj2.Pos() && obj1.Name() == obj2.Name()
619+
}
620+
611621
// effectiveReceiver returns the effective receiver type for method-set
612622
// comparisons for obj, if it is a method, or nil otherwise.
613623
func effectiveReceiver(obj types.Object) types.Type {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Regression test for 'references' bug golang/go#61618:
2+
references to instantiated fields were missing.
3+
4+
-- flags --
5+
-min_go=go1.18
6+
7+
-- go.mod --
8+
module example.com
9+
go 1.18
10+
11+
-- a.go --
12+
package a
13+
14+
// This file is adapted from the example in the issue.
15+
16+
type builder[S ~[]F, F ~string] struct {
17+
name string
18+
elements S //@loc(def, "elements"), refs(def, def, assign, use)
19+
elemData map[F][]ElemData[F]
20+
}
21+
22+
type ElemData[F ~string] struct {
23+
Name F
24+
}
25+
26+
type BuilderImpl[S ~[]F, F ~string] struct{ builder[S, F] }
27+
28+
func NewBuilderImpl[S ~[]F, F ~string](name string) *BuilderImpl[S, F] {
29+
impl := &BuilderImpl[S,F]{
30+
builder[S, F]{
31+
name: name,
32+
elements: S{}, //@loc(assign, "elements"), refs(assign, def, assign, use)
33+
elemData: map[F][]ElemData[F]{},
34+
},
35+
}
36+
37+
_ = impl.elements //@loc(use, "elements"), refs(use, def, assign, use)
38+
return impl
39+
}

0 commit comments

Comments
 (0)