Skip to content

x/tools/gopls: adding gopls as a tool dependency leads to build failures #73279

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

Open
corani opened this issue Apr 9, 2025 · 12 comments
Open
Labels
BugReport Issues describing a possible bug in the Go implementation. gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@corani
Copy link

corani commented Apr 9, 2025

gopls version

	golang.org/x/tools v0.32.0 // indirect
	golang.org/x/tools/gopls v0.18.1 // indirect

go env

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='snip/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='snip/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2682111243=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='snip/go.mod'
GOMODCACHE='snip/go/pkg/mod'
GONOPROXY='snip'
GONOSUMDB='*'
GOOS='linux'
GOPATH='snip/go'
GOPRIVATE='snip'
GOPROXY='snip'
GOROOT='snip/go/pkg/mod/golang.org/[email protected]'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='snip/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='snip/go/pkg/mod/golang.org/[email protected]/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

go tool modernize --fix ./...

What did you see happen?

# golang.org/x/tools/gopls/internal/analysis/modernize
vendor/golang.org/x/tools/gopls/internal/analysis/modernize/bloop.go:167:29: c.Ancestors undefined (type cursor.Cursor has no field or method Ancestors)
vendor/golang.org/x/tools/gopls/internal/analysis/modernize/rangeint.go:156:15: cur.Edge undefined (type cursor.Cursor has no field or method Edge)
vendor/golang.org/x/tools/gopls/internal/analysis/modernize/rangeint.go:159:15: cur.Edge undefined (type cursor.Cursor has no field or method Edge)
vendor/golang.org/x/tools/gopls/internal/analysis/modernize/splitseq.go:55:30: curRange.Edge undefined (type cursor.Cursor has no field or method Edge)
vendor/golang.org/x/tools/gopls/internal/analysis/modernize/testingcontext.go:113:26: curFunc.Edge undefined (type cursor.Cursor has no field or method Edge)

What did you expect to see?

no errors :)

Editor and settings

No response

Logs

No response

@corani corani added gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. labels Apr 9, 2025
@gopherbot gopherbot added this to the Unreleased milestone Apr 9, 2025
@corani
Copy link
Author

corani commented Apr 9, 2025

Release of x/[email protected] has broken modernize. Version on master seems already fixed, could this be released ASAP?

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Apr 9, 2025
@adonovan
Copy link
Member

adonovan commented Apr 9, 2025

go tool modernize --fix ./...

Where did this command come from? (Is there some incorrect documentation recommending it?)

go tool locates executables of the Go toolchain; but modernize is an internal command of the golang.org/x/tools/gopls module. The command you want is this (or go install followed by just modernize):

$ go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...

Release of x/[email protected] has broken modernize. Version on master seems already fixed, could this be released ASAP?

What command did you run? Unless you have git clone of x/tools, you cannot build versions of gopls that are not on a release branch.

@corani
Copy link
Author

corani commented Apr 10, 2025

Where did this command come from?

From go get -tool golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest.

I use this to pin the exact version of tools I'm using in our CI/CD pipelines, to ensure reproducible builds. Previously I was using a sub-module with a tools.go to pin the versions, I've recently changed this to use the new tool directive in the main go.mod.

Dependency updates are coming from Renovate, which is trying to update x/tools now, most likely due to a similar dependency on golang.org/x/tools/cmd/stringer.

@enckse
Copy link

enckse commented Apr 10, 2025

I've also run into this issue (I used go get -tool golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest much like @corani ).

Where did this command come from? (Is there some incorrect documentation recommending it?)

Specifically wanted to add to this, I don't think there is any documentation necessarily recommending to use go get -tool ... and go tool modernize ... (in this case) as much as it is very handy to be able to version the modernize command along with anything else of interest in go.mod and go get -tool certainly didn't stop me.

@alexaandru
Copy link

Me too. I used go get tool to update the tools (which included modernize) and then modernize was breaking as above.

@adonovan
Copy link
Member

@matloob, is this an interaction between vendoring of x/tools in goroot and the new go get -tool/go tool feature?

@corani
Copy link
Author

corani commented Apr 14, 2025

To reproduce:

$ cd $(mktemp -d)

$ go mod init example
go: creating new go.mod: module example

$ go get -tool golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest
go: added golang.org/x/mod v0.23.0
go: added golang.org/x/sync v0.11.0
go: added golang.org/x/tools v0.30.1-0.20250221230316-5055f70f240c
go: added golang.org/x/tools/gopls v0.18.1

$ go get -tool golang.org/x/tools/cmd/stringer@latest
go: upgraded golang.org/x/mod v0.23.0 => v0.24.0
go: upgraded golang.org/x/sync v0.11.0 => v0.13.0
go: upgraded golang.org/x/tools v0.30.1-0.20250221230316-5055f70f240c => v0.32.0

$ go tool modernize
# golang.org/x/tools/gopls/internal/analysis/modernize
$HOME/go/pkg/mod/golang.org/x/tools/[email protected]/internal/analysis/modernize/bloop.go:167:29: c.Ancestors undefined (type cursor.Cursor has no field or method Ancestors)
$HOME/go/pkg/mod/golang.org/x/tools/[email protected]/internal/analysis/modernize/rangeint.go:156:15: cur.Edge undefined (type cursor.Cursor has no field or method Edge)
$HOME/go/pkg/mod/golang.org/x/tools/[email protected]/internal/analysis/modernize/rangeint.go:159:15: cur.Edge undefined (type cursor.Cursor has no field or method Edge)
$HOME/go/pkg/mod/golang.org/x/tools/[email protected]/internal/analysis/modernize/splitseq.go:55:30: curRange.Edge undefined (type cursor.Cursor has no field or method Edge)
$HOME/go/pkg/mod/golang.org/x/tools/[email protected]/internal/analysis/modernize/testingcontext.go:113:26: curFunc.Edge undefined (type cursor.Cursor has no field or method Edge)

$ cat go.mod
module example

go 1.24.1

tool (
        golang.org/x/tools/cmd/stringer
        golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize
)

require (
        golang.org/x/mod v0.24.0 // indirect
        golang.org/x/sync v0.13.0 // indirect
        golang.org/x/tools v0.32.0 // indirect
        golang.org/x/tools/gopls v0.18.1 // indirect
)

Note: stringer is just one example, but many other modules cause this breakage due to a dependency on x/[email protected] (for example: github.com/mvdan/[email protected])

@thepudds
Copy link
Contributor

Where did this command come from? (Is there some incorrect documentation recommending it?)

go tool locates executables of the Go toolchain; but modernize is an internal command of the golang.org/x/tools/gopls module. The command you want is this (or go install followed by just modernize):

$ go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...

Hi @adonovan, I suspect the new go tool support in Go 1.24 is so convenient that people might over use it.

I think the reason for the behavior in @corani's example in #73279 (comment) is briefly explained in the documentation:

Requirements needed to satisfy tool dependencies behave like any other requirements in your module graph. They participate in minimal version selection [...]

It would probably be good to better document some of the alternatives to using go tool. See for example #71663 and https://go.dev/cl/648578, which seem like they need some more discussion to work out what we want to do.

@adonovan
Copy link
Member

adonovan commented Apr 15, 2025

Thanks @corani and @thepudds, that explains it. The issue here is that the modernize command, currently (but not fundamentally) part of the gopls module, is governed by the gopls release process, and you can't just upgrade the x/tools package to a later one, as happens when installing stringer, because the gopls release branch needs a particular version and x/tools does not present a stable internal API to gopls. In short, no-one should ever add gopls as a module dependency, and that means you cannot use go get -tool with gopls. I will update the documentation to make this clear.

@matloob mentioned that there was a discussion during the design of the -tool feature as to whether each tool command should have its own constraint system, or whether all of them should be subject to a single set of constraints. This behavior is a consequence of using a single constraint system. He also mentioned that one could also argue that the way gopls uses x/tools is an abuse of semantic versioning.

@adonovan adonovan changed the title x/tools/gopls: type cursor.Cursor has no field or method Ancestors) x/tools/gopls: adding gopls as a tool dependency leads to build failures Apr 15, 2025
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/665636 mentions this issue: gopls: warn against using go get -tool with gopls

gopherbot pushed a commit to golang/tools that referenced this issue Apr 15, 2025
The problem is that gopls needs exactly the right version
of x/tools, as found on its release branch. The solution
to an MVS constraint system which requires x/tools at
higher versions will inevitably lead to build failures.

(We should move modernize to x/tools.)

Updates golang/go#73279

Change-Id: I6f43bb2e74b29384cedcb92b5d958cf695aa529d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/665636
Reviewed-by: Robert Findley <[email protected]>
Auto-Submit: Alan Donovan <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/665637 mentions this issue: gopls: improve warning against using go get -tool with gopls

gopherbot pushed a commit to golang/tools that referenced this issue Apr 15, 2025
(Belatedly addresses review comments on CL 665636.)

Updates golang/go#73279

Change-Id: I03c2e5e2306f7c6de349e7d11ba87df6332622f5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/665637
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
Auto-Submit: Alan Donovan <[email protected]>
haines added a commit to cerbos/cerbos-sdk-go that referenced this issue Apr 15, 2025
haines added a commit to cerbos/cloud-api that referenced this issue Apr 15, 2025
haines added a commit to cerbos/cloud-api that referenced this issue Apr 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

7 participants