-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: go directive is insufficiently documented for module authors to be able to make a decision about its value #30791
Comments
I'm sure we should write better docs. The basic guideline is fairly simple: a "go" directive 1.N means that the code in that module is permitted to use language features that existed in 1.N even if those features were removed in later releases of the language. In other words, if the code compiles successfully at version 1.N, then it will continue to compile for all later versions of the language, even if it happens to use language features that were later removed. To a first approximation, nobody should ever have to worry about the "go" directive. The only likely time you might need to set it manually is if you are copying some existing code to a new module, that code uses some obsolete language feature, and you don't have time to rewrite it. In that case you might want to set the "go" directive (using |
My understanding of #28221 is that it should not only permit the older features, but also prohibit newer features. Otherwise, there is little incentive for folks to upgrade to a language version beyond the removed features: they can just set That understanding is based on this part of the proposal discussion:
That has an interesting interaction with build tags, though: if I set |
I would argue that a Or perhaps it should result in an explicit error, since the user may otherwise be confused that it has no effect. |
(CC @jayconrod) |
Those are good questions. When looking for an answer, we should make sure that authors who wish to create Go modules that work with a wide range of Go versions (e.g., 1.8–1.12 as |
I made similar conclusions based on that type alias example. When I asked Ian about it, his response was:
Which made me understand that the type alias example can be misleading when thinking about how the |
I will write some docs. |
See #31747 too. |
On the basis of this, it seems like an odd behaviour for go test to attempt to mutate the go.mod file if there is no go directive line. If I have a go mod file that makes no claims about the language version, I would think under the model quoted, that should be respected. Real world justification (reaching because of lack of docs): if a module is aimed at a number of go versions, how is that specified? |
@kortschak, regarding your comment above about the interaction with build tags, also worth reading #31747 (comment) if you haven’t already. |
Thanks, @thepudds. |
Change https://golang.org/cl/181840 mentions this issue: |
Updates #30791 Change-Id: I67efd7fd3b3a550428b16518bb27a3d81c178d28 Reviewed-on: https://go-review.googlesource.com/c/go/+/181840 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
Although not entirely within the scope of this issue a related piece of feedback I have seen (and heard many times more) is that the meaning of the The overwhelming reaction is that people believe that it will enforce a specific Go toolchain to be used. As in running your local Go 1.13 toolchain on a module with a The only real documentation that can be found on the web appears to be the 1.12 release notes (already referenced in the issue description) which leaves enough space for people to come to such a conclusion. Source (one amongst many): golangci/golangci-lint#605 (comment) |
FWIW, I have seen a fair amount of confusion on this topic as well. Now that the playground is running Go 1.13, here is a trivial example that illustrates one aspect of the expected behavior. Setting the Go language version to https://play.golang.org/p/Mb7imkDHhoz The current error is:
In contrast, setting the Go language version in the go.mod to https://play.golang.org/p/VokbN-hHq02 That (I think?) illustrates how the One particular aspect of confusion is people end up debating each other on random issues on open source projects regarding what the I think it would be helpful if there was a small bit of advice in the documentation on that piece, and I'm not sure "whatever cmd/go picks" is what most projects should be doing currently, or at least there is some nuance to the choice. (If someone asked me, and if that someone does not yet want to use newer language features like signed integer shifts, then I'd probably personally recommend |
So just to clarify, the version set in the Further, an older version of go will attempt to compile and not complain about compiling a module that specifies a newer version of go, assuming compilation succeeds? |
The So module authors should now have sufficient information needed to able to make a decision about what value to use in their modules. Closing, since this issue was resolved in Go 1.21. |
Go 1.12 has added a
go
directive to the go.mod file. It's documented in the following places.At https://golang.org/doc/go1.12#modules:
Additionally, a relevant paragraph from https://golang.org/doc/go1.12#compiler:
At https://golang.org/cmd/go/#hdr-The_go_mod_file:
There is additional information available in issues, proposals, commit messages and code review comments, which I did not mention above. However, that information is not readily accessible to users.
It is very common for package authors to aim to ensure their Go packages can be used in multiple versions of Go. Sometimes it's just Go 1.12.x and Go 1.11.x (the current and previous releases). Other times the goal is to support even older versions of Go. This often includes running tests in CI with those versions of Go to ensure that the build and tests are successful. When these package authors add a go.mod file file to their repositories, they should be able to make a sensible decision about what
go
directive should be included.Problem
I believe the current documentation is not sufficient for module authors to make a well-informed decision on whether to include the
go
directive in their go.mod files, and if so, what the value of thego
directive should be.I think we should try to improve documentation to resolve that. But first I want to make sure others agree that it's a problem.
(This is based on looking over the discussions that have happened around various PRs/CLs where the
go
directive is introduced, often by people who are very familiar with modules. Sometimes this happens more often due to #30790.)/cc @ianlancetaylor @dsnet @bcmills @julieqiu @heschik @matloob
The text was updated successfully, but these errors were encountered: