-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
go/ast, go/build/constraint: support for per-file Go versions using //go:build lines #59033
Comments
Change https://go.dev/cl/476275 mentions this issue: |
Change https://go.dev/cl/476276 mentions this issue: |
Change https://go.dev/cl/476277 mentions this issue: |
Change https://go.dev/cl/476278 mentions this issue: |
It seems like this does slightly interfere with "all developers working on a project will agree on the toolchain version"; if I am using 1.22, someone else is using 1.23, the app under development has a 1.21 go.mod minimum version but contains files with 1.23 build tags, the two of us will see different builds of the app. I still want this change, though. |
All developers still get the same, reproducible build. That build just agrees on which files use which Go dialects. I don't think this conflicts with that. |
I should add a ! example; GoVersion(!go1.22) = "". |
This proposal has been added to the active column of the proposals project |
Is there a comment in the prior issue which summarizes the use case for having an older toolchain version for an individual file then the minimum go version in the module? It seems like a strange case to me. |
If you are updating and know that the older file needs older semantics, you can set the default for the module (to cover new files created there) and then special-case the few files you need older semantics in. |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
For #57001, programs need to be able to deduce the Go version implied by a given build constraint. GoVersion determines that, by discarding all build tags other than Go versions and computing the minimum Go version implied by the resulting expression. For #59033. Change-Id: Ifb1e7af2bdbdf172f82aa490c826c9b6ca5e824b Reviewed-on: https://go-review.googlesource.com/c/go/+/476275 Run-TryBot: Russ Cox <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Auto-Submit: Russ Cox <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
For #57001, compilers and others tools will need to understand that a different Go version can be used in different files in a program, according to the //go:build lines in those files. This CL adds a GoVersion string field to ast.File, to allow exposing this per-file Go version information. For #59033. Change-Id: I3931ea86c237983d152964f48dce498bcb1f06aa Reviewed-on: https://go-review.googlesource.com/c/go/+/476276 Run-TryBot: Russ Cox <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Russ Cox <[email protected]>
For #57001, compilers and others tools will need to understand that a different Go version can be used in different files in a program, according to the //go:build lines in those files. Update go/parser to populate the new ast.File.GoVersion field. This requires running the go/scanner in ParseComments mode always and then implementing discarding of comments in the parser instead of the scanner. The same work is done either way, since the scanner was already preparing the comment result and then looping. The loop has just moved into go/parser. Also make the same changes to cmd/compile/internal/syntax, both because they're necessary and to keep in sync with go/parser. For #59033. Change-Id: I7b867f5f9aaaccdca94af146b061d16d9a3fd07f Reviewed-on: https://go-review.googlesource.com/c/go/+/476277 Auto-Submit: Russ Cox <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Russ Cox <[email protected]>
For #57001, compilers and others tools will need to understand that a different Go version can be used in different files in a program, according to the //go:build lines in those files. Update go/types and cmd/compile/internal/types2 to track and use per-file Go versions. The two must be updated together because of the files in go/types that are generated from files in types2. The effect of the //go:build go1.N line depends on the Go version declared in the 'go 1.M' line in go.mod. If N > M, the file gets go1.N semantics when built with a Go 1.N or later toolchain (when built with an earlier toolchain the //go:build line will keep the file from being built at all). If N < M, then in general we want the file to get go1.N semantics as well, meaning later features are disabled. However, older Go 1.M did not apply this kind of downgrade, so for compatibility, N < M only has an effect when M >= 21, meaning when using semantics from Go 1.21 or later. For #59033. Change-Id: I93cf07e6c687d37bd37a9461dc60cc032bafd01d Reviewed-on: https://go-review.googlesource.com/c/go/+/476278 TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Russ Cox <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Run-TryBot: Russ Cox <[email protected]>
Change https://go.dev/cl/499415 mentions this issue: |
For #56986 For #59033 Change-Id: I7d03fe34d418aff97a551b236b5d43506e402871 Reviewed-on: https://go-review.googlesource.com/c/go/+/499415 TryBot-Bypass: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]>
I think this was implemented in Go 1.21. @rsc, is there anything more to do for it? |
|
Done! |
As part of the discussion during the acceptance of #57001, we decided the following.
go
line in go.mod as the minimum Go version required. For example if Go 1.21 encounters a go.mod file that saysgo 1.22
, it will refuse to build code in that module.//go:build
constraints that require a newer Go version than the go.modgo
line and allow newer Go features in those files. We are also going to allow a//go:build
constraint to declare an older version, which will lock out newer Go features that would normally be allowed by the go.modgo
version. For compatibility reasons, that “downgrading” can only apply for go.mod files sayinggo 1.21
or later.To implement (2), we need a small amount of new API: go/build/constraint needs to export code to compute the implied minimum Go version from a constraint.Expr, and go/ast needs to expose the minimum Go version as a new field in ast.File.
This proposal is about that new API. I propose:
And
go/parser would populate ast.File.GoVersion, and go/types would use that information to decide whether specific features are allowed in certain files.
The text was updated successfully, but these errors were encountered: