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

cmd/go: using go get go@{version} in a module without a go directive can print a misleading "downgraded" message #63507

Open
dmitshur opened this issue Oct 11, 2023 · 1 comment
Labels
GoCommand cmd/go modules NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@dmitshur
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.21.3 darwin/arm64

What did you do?

https://go.dev/ref/mod#go-mod-file-go specifies:

If the go directive is missing, go 1.16 is assumed.

Consider:

$ cat go.mod
module example.com/m
$ cat p.go 
package p; import "cmp"; var _ = cmp.Less(1, 2)

The error message that go test prints is consistent with that (provided it's not due to #63489):

$ go test
# example.com/m
./p.go:1:34: implicit function instantiation requires go1.18 or later (-lang was set to go1.16; check go.mod)

But when doing something like go get go@1.20 (or go mod tidy), the module appears to behave as if it implicitly had the go command's version instead of 1.16.

What did you expect to see?

$ go get go@1.20
go: upgraded go 1.16 => 1.20
go: added toolchain go1.21.3

What did you see instead?

$ go get go@1.20
go: downgraded go 1.21.3 => 1.20
go: added toolchain go1.21.3

CC @rsc, @bcmills.

@dmitshur dmitshur added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. GoCommand cmd/go modules labels Oct 11, 2023
@dmitshur dmitshur added this to the Backlog milestone Oct 11, 2023
@bcmills
Copy link
Contributor

bcmills commented Oct 12, 2023

The downgraded message is definitely misleading, and we should definitely fix that. 😅

The asymmetric behavior is intentional, though. When we first introduced the go directive we had the property that commands that add it always add the current version, not an old version. But we also have compatibility to contend with, meaning that a go command in a very old repo should use the semantics appropriate to that repo.

Those two goals are in tension, and the way we resolved that tension is: if we are going to write out a go version in a module that did not have one, we write the current version, but if we are not going to write it out we assume an old (and very widely compatible) version.

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Oct 12, 2023
@dmitshur dmitshur changed the title cmd/go: module without a go directive doesn't consistently behave as if it had a 1.16 go directive cmd/go: using go get go@{version} in a module without a go directive can print a misleading "downgraded" message Oct 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GoCommand cmd/go modules NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

2 participants