Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/cmd/go/internal/gover/toolchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ func FromToolchain(name string) string {
return v
}

// ToolchainForGoVersion returns the implied toolchain name for the Go version v.
func ToolchainForGoVersion(v string) string {
name := "go" + v
if IsLang(v) && Compare(v, GoStrictVersion) >= 0 {
name += ".0"
}
return name
}

func maybeToolchainVersion(name string) string {
if IsValid(name) {
return name
Expand Down
13 changes: 13 additions & 0 deletions src/cmd/go/internal/gover/toolchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,16 @@ var fromToolchainTests = []testCase1[string, string]{
{"gccgo-go1.23rc4", ""},
{"gccgo-go1.23rc4-bigdwarf", ""},
}

func TestToolchainForGoVersion(t *testing.T) {
test1(t, toolchainForGoVersionTests, "ToolchainForGoVersion", ToolchainForGoVersion)
}

var toolchainForGoVersionTests = []testCase1[string, string]{
{"1.20", "go1.20"},
{"1.21", "go1.21.0"},
{"1.22", "go1.22.0"},
{"1.23", "go1.23.0"},
{"1.23.4", "go1.23.4"},
{"1.24rc1", "go1.24rc1"},
}
8 changes: 5 additions & 3 deletions src/cmd/go/internal/modload/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,8 +918,9 @@ func UpdateWorkGoVersion(wf *modfile.WorkFile, goVers string) (changed bool) {
// This behavior seemed to cause user confusion without much
// benefit so it was removed. See #65847.
toolchain := wf.Toolchain.Name
impliedToolchain := gover.ToolchainForGoVersion(goVers)
toolVers := gover.FromToolchain(toolchain)
if toolchain == "go"+goVers || gover.Compare(toolVers, goVers) < 0 || gover.Compare(toolVers, gover.GoStrictVersion) < 0 {
if toolchain == "go"+goVers || toolchain == impliedToolchain || gover.Compare(toolVers, goVers) < 0 || gover.Compare(toolVers, gover.GoStrictVersion) < 0 {
wf.DropToolchainStmt()
}

Expand Down Expand Up @@ -2012,11 +2013,12 @@ func UpdateGoModFromReqs(ld *Loader, ctx context.Context, opts WriteOpts) (befor
forceGoStmt(modFile, mainModule, gover.GoModToolVersion)
}

impliedToolchain := gover.ToolchainForGoVersion(goVersion)
if toolchain == "" {
toolchain = "go" + goVersion
toolchain = impliedToolchain
}
toolVers := gover.FromToolchain(toolchain)
if opts.DropToolchain || toolchain == "go"+goVersion || (gover.Compare(toolVers, gover.GoStrictVersion) < 0 && !opts.ExplicitToolchain) {
if opts.DropToolchain || toolchain == "go"+goVersion || toolchain == impliedToolchain || (gover.Compare(toolVers, gover.GoStrictVersion) < 0 && !opts.ExplicitToolchain) {
// go get toolchain@none or toolchain matches go line or isn't valid; drop it.
// TODO(#57001): 'go get' should reject explicit toolchains below GoStrictVersion.
modFile.DropToolchainStmt()
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/modload/modfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ func rawGoModSummary(ld *Loader, m module.Version) (*modFileSummary, error) {
// Declare that go 1.21.3 requires toolchain 1.21.3,
// so that go get knows that downgrading toolchain implies downgrading go
// and similarly upgrading go requires upgrading the toolchain.
return &modFileSummary{module: m, require: []module.Version{{Path: "toolchain", Version: "go" + m.Version}}}, nil
return &modFileSummary{module: m, require: []module.Version{{Path: "toolchain", Version: gover.ToolchainForGoVersion(m.Version)}}}, nil
}
return &modFileSummary{module: m}, nil
}
Expand Down
7 changes: 2 additions & 5 deletions src/cmd/go/internal/toolchain/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,12 @@ func Select() {
}
}
if gover.Compare(goVers, minVers) > 0 {
gotoolchain = "go" + goVers
minVers = goVers
// Starting with Go 1.21, the first released version has a .0 patch version suffix.
// Don't try to download a language version (sans patch component), such as go1.22.
// Instead, use the first toolchain of that language version, such as 1.22.0.
// See golang.org/issue/62278.
if gover.IsLang(goVers) && gover.Compare(goVers, "1.21") >= 0 {
gotoolchain += ".0"
}
gotoolchain = gover.ToolchainForGoVersion(goVers)
minVers = goVers
gover.Startup.AutoGoVersion = goVers
gover.Startup.AutoToolchain = "" // in case we are overriding it for being too old
if toolchainTrace {
Expand Down
25 changes: 25 additions & 0 deletions src/cmd/go/testdata/script/mod_get_toolchain.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ grep 'toolchain go1.23.9' go.mod

# Bug fixes.

# go get go@version should not write a language version as the toolchain when
# preserving the original go line's implied toolchain.
cp go.mod.oldlang go.mod
go get go@1.22.9
stderr '^go: downgraded go 1.23 => 1.22.9$'
stderr '^go: upgraded toolchain go1.22.9 => go1.23.0$'
grep '^go 1.22.9$' go.mod
grep '^toolchain go1.23.0$' go.mod
! grep '^toolchain go1.23$' go.mod
cp go.mod.latest go.mod

# go get go@garbage should fail but not crash
! go get go@garbage
! stderr panic
Expand Down Expand Up @@ -134,3 +145,17 @@ grep 'go 1.21$' go.mod
module m

go 1.21

-- go.mod.oldlang --
module m

go 1.23

toolchain go1.22.9

-- go.mod.latest --
module m

go 1.21

toolchain go1.23.9
Loading