Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types: position of field Var S.T in type S struct{ p.T } coincides with p, not T #60372

Closed
adonovan opened this issue May 23, 2023 · 2 comments
Assignees

Comments

@adonovan
Copy link
Member

adonovan commented May 23, 2023

When go/types encounters an embedded (unnamed) field, it uses the Pos of the ast.Field syntax node as the Pos of the field types.Var object. If the field type is a qualified identifier p.T, this means that the source code at the position of the declaration of struct field T does not contain an identifier "T". Instead, the source at that position is the package identifier "p".

I realize these invariants are not as well formalized as we would like, but I argue this is a bug. It should use the Pos of the type name identifier in all cases.

The relevant source is in go/types/struct.go, Checker.structType:

func (check *Checker) structType(styp *Struct, e *ast.StructType) {
...
	for _, f := range list.List {
		typ = check.varType(f.Type)
		tag = check.tag(f.Tag)
		if len(f.Names) > 0 {
			// named fields
			...
		} else {
			// embedded field
			// spec: "An embedded type must be specified as a type name T or as a
			// pointer to a non-interface type name *T, and T itself may not be a
			// pointer type."
			pos := f.Type.Pos() // <--------------HERE
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/497495 mentions this issue: gopls/internal/lsp/source: fix references bug on struct{p.T}

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/497882 mentions this issue: go/types: set correct Pos for T in struct{p.T}

gopherbot pushed a commit to golang/tools that referenced this issue May 25, 2023
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>
@golang golang locked and limited conversation to collaborators May 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants