Skip to content

Commit

Permalink
[release-branch.go1.19] cmd/go: refuse to build Go 1.22 code
Browse files Browse the repository at this point in the history
With #60078 accepted, we expect Go 1.22 will have different
for loop semantics than Go 1.19 did.
Go 1.19 is already unsupported, but add a check anyway, just to
help catch some mistakes and usage of old Go toolchains
beyond their end-of-support.

Note that Go 1.19 can keep being used indefinitely with pre-Go 1.22 code.
This change only makes it refuse to build code that says it needs
Go 1.22 semantics, because Go 1.19 does not provide those.

Cherry-pick of the change from the Go 1.20 branch.

For #60078.

Change-Id: I75118d6fbd0cc08a6bc309aca54c389a255ba7dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/518675
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/518815
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Bypass: Russ Cox <rsc@golang.org>
  • Loading branch information
rsc authored and gopherbot committed Aug 11, 2023
1 parent 0ae54dd commit 2f498f2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
12 changes: 12 additions & 0 deletions src/cmd/go/internal/work/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,18 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
return errors.New("binary-only packages are no longer supported")
}

// Go 1.22 is likely to change for loop semantics.
// If we try to build code written for Go 1.22,
// it may have aliasing bugs that it shouldn't have.
// See go.dev/issue/60078.
// Go 1.19 is no longer supported,
// but we are adding this check anyway,
// just to help catch some mistakes and usage of old
// Go toolchains beyond their end-of-support.
if p.Module != nil && !(allowedVersion(p.Module.GoVersion) || p.Module.GoVersion == "1.20" || p.Module.GoVersion == "1.21") {
return errors.New("cannot compile Go " + p.Module.GoVersion + " code")
}

if err := b.Mkdir(a.Objdir); err != nil {
return err
}
Expand Down
44 changes: 44 additions & 0 deletions src/cmd/go/testdata/script/build_go122.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
! go build
stderr '^m: cannot compile Go 1.22 code$'

cd dep
! go build
stderr '^m: cannot compile Go 1.22 code$'

cd ../dep20
go build

cd ../dep21
go build

-- go.mod --
module m
go 1.22

-- p.go --
package p

-- dep/go.mod --
module dep
go 1.19
require m v1.0.0
replace m v1.0.0 => ../

-- dep/p.go --
package p

import "m"

-- dep20/go.mod --
module dep
go 1.20

-- dep20/p.go --
package p

-- dep21/go.mod --
module dep
go 1.21

-- dep21/p.go --
package p
14 changes: 7 additions & 7 deletions src/cmd/go/testdata/script/mod_go_version.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ go build sub.1
go build subver.1
! stderr 'module requires'
! go build badsub.1
stderr '^note: module requires Go 1.11111$'
stderr '^note: module requires Go 1.21$'

go build versioned.1
go mod edit -require versioned.1@v1.1.0
! go build versioned.1
stderr '^note: module requires Go 1.99999$'
stderr '^note: module requires Go 1.21$'

[short] stop

# The message should be printed even if the compiler emits no output.
go build -o $WORK/nooutput.exe nooutput.go
! go build -toolexec=$WORK/nooutput.exe versioned.1
stderr '^# versioned.1\nnote: module requires Go 1.99999$'
stderr '^# versioned.1\nnote: module requires Go 1.21$'

-- go.mod --
module m
go 1.999
go 1.21
require (
sub.1 v1.0.0
subver.1 v1.0.0
Expand All @@ -51,14 +51,14 @@ package x

-- subver/go.mod --
module m
go 1.11111
go 1.21

-- subver/x.go --
package x

-- badsub/go.mod --
module m
go 1.11111
go 1.21

-- badsub/x.go --
package x
Expand All @@ -73,7 +73,7 @@ package x

-- versioned2/go.mod --
module versioned
go 1.99999
go 1.21

-- versioned2/x.go --
package x
Expand Down

0 comments on commit 2f498f2

Please sign in to comment.