diff --git a/src/cmd/go/internal/toolchain/select.go b/src/cmd/go/internal/toolchain/select.go index cbdd7a2418e..aeab59519c7 100644 --- a/src/cmd/go/internal/toolchain/select.go +++ b/src/cmd/go/internal/toolchain/select.go @@ -169,7 +169,7 @@ func Select() { } gotoolchain = minToolchain - if (mode == "auto" || mode == "path") && !goInstallVersion() { + if (mode == "auto" || mode == "path") && !goInstallVersion(minVers) { // Read go.mod to find new minimum and suggested toolchain. file, goVers, toolchain := modGoToolchain() gover.Startup.AutoFile = file @@ -549,7 +549,7 @@ func modGoToolchain() (file, goVers, toolchain string) { // goInstallVersion reports whether the command line is go install m@v or go run m@v. // If so, Select must not read the go.mod or go.work file in "auto" or "path" mode. -func goInstallVersion() bool { +func goInstallVersion(minVers string) bool { // Note: We assume there are no flags between 'go' and 'install' or 'run'. // During testing there are some debugging flags that are accepted // in that position, but in production go binaries there are not. @@ -708,7 +708,11 @@ func goInstallVersion() bool { if errors.Is(err, gover.ErrTooNew) { // Run early switch, same one go install or go run would eventually do, // if it understood all the command-line flags. - SwitchOrFatal(ctx, err) + var s Switcher + s.Error(err) + if s.TooNew != nil && gover.Compare(s.TooNew.GoVersion, minVers) > 0 { + SwitchOrFatal(ctx, err) + } } return true // pkg@version found diff --git a/src/cmd/go/testdata/script/gotoolchain_local.txt b/src/cmd/go/testdata/script/gotoolchain_local.txt index db7e082db96..8bece6ebd84 100644 --- a/src/cmd/go/testdata/script/gotoolchain_local.txt +++ b/src/cmd/go/testdata/script/gotoolchain_local.txt @@ -197,6 +197,17 @@ go mod edit -go=1.501 -toolchain=none go version stdout go1.501 +# avoid two-step switch, first from install target requirement, then from GOTOOLCHAIN min +# instead, just jump directly to GOTOOLCHAIN min +env TESTGO_VERSION=go1.2.3 +env GODEBUG=toolchaintrace=1 +env GOTOOLCHAIN=go1.23.0+auto +! go install rsc.io/fortune/nonexist@v0.0.1 +! stderr 'switching to go1.22.9' +stderr 'using go1.23.0' +env GODEBUG= +env GOTOOLCHAIN=auto + # go install m@v and go run m@v should ignore go.mod and use m@v env TESTGO_VERSION=go1.2.3 go mod edit -go=1.999 -toolchain=go1.998