Skip to content

Commit 827f5aa

Browse files
committed
gopls/internal/lsp/source: test references bug on struct{p.T}
This change adds a regression test for bug in gopls' references operation applied to the T identifier in an embedded struct field such as struct{p.T): instead of reporting references to T, it reports references to package name p. This is a consequence of go/types bug golang/go#60372, which sets the position of the struct field types.Var to that of the ast.Field syntax (p) not the type name (T). The bug was fixed in go1.21. Updates golang/go#60372 Fixes golang/go#60369 Change-Id: Ibabe885ea689b30d966dbf7e51f8c25e44a6ce1c Reviewed-on: https://go-review.googlesource.com/c/tools/+/497495 gopls-CI: kokoro <noreply+kokoro@google.com> Run-TryBot: Alan Donovan <adonovan@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
1 parent a12e1a6 commit 827f5aa

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

gopls/internal/lsp/source/references.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func ordinaryReferences(ctx context.Context, snapshot Snapshot, uri span.URI, pp
224224
}
225225

226226
// Find the selected object (declaration or reference).
227+
// For struct{T}, we choose the field (Def) over the type (Use).
227228
pos, err := pgf.PositionPos(pp)
228229
if err != nil {
229230
return nil, err
@@ -649,6 +650,13 @@ func objectsAt(info *types.Info, file *ast.File, pos token.Pos) (map[types.Objec
649650
targets[obj] = leaf
650651
}
651652
} else {
653+
// Note: prior to go1.21, go/types issue #60372 causes the position
654+
// a field Var T created for struct{*p.T} to be recorded at the
655+
// start of the field type ("*") not the location of the T.
656+
// This affects references and other gopls operations (issue #60369).
657+
// TODO(adonovan): delete this comment when we drop support for go1.20.
658+
659+
// For struct{T}, we prefer the defined field Var over the used TypeName.
652660
obj := info.ObjectOf(leaf)
653661
if obj == nil {
654662
return nil, nil, fmt.Errorf("%w for %q", errNoObjectFound, leaf.Name)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Regression test for 'references' bug golang/go#60369: a references
2+
query on the embedded type name T in struct{p.T} instead reports all
3+
references to the package name p.
4+
5+
The bug was fixed in release go1.21 of go/types.
6+
7+
-- flags --
8+
-min_go=go1.21
9+
10+
-- go.mod --
11+
module example.com
12+
go 1.12
13+
14+
-- a/a.go --
15+
package a
16+
17+
type A struct{}
18+
const C = 0
19+
20+
-- b/b.go --
21+
package b
22+
23+
import a "example.com/a" //@loc(adef, "a")
24+
type s struct { a.A } //@loc(Aref1, "A"), loc(aref1, "a"), refs(Aref1, Aref1, Aref3), refs(aref1, adef, aref1, aref2, aref3)
25+
var _ a.A //@loc(aref2, re" (a)"), loc(Aref2, "A")
26+
var _ = s{}.A //@loc(Aref3, "A")
27+
const c = a.C //@loc(aref3, "a")

0 commit comments

Comments
 (0)