[24.0 backport] add //go:build directives to prevent downgrading to go1.16 language #4829
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a follow-up to 0e73168
This repository is not yet a module (i.e., does not have a
go.mod). This is not problematic when building the code in GOPATH or "vendor" mode, but when using the code as a module-dependency (in module-mode), different semantics are applied since Go1.21, which switches Go language versions on a per-module, per-package, or even per-file base.A condensed summary of that logic [is as follows][1]:
When switching language versions, Go downgrades the language version, which means that language features (such as generics, and
any) are not available, and compilation fails. For example:Note that these fallbacks are per-module, per-package, and can even be per-file, so (indirect) dependencies can still use modern language features, as long as their respective go.mod has a version specified.
Unfortunately, these failures do not occur when building locally (using vendor / GOPATH mode), but will affect consumers of the module.
Obviously, this situation is not ideal, and the ultimate solution is to move to go modules (add a go.mod), but this comes with a non-insignificant risk in other areas (due to our complex dependency tree).
We can revert to using go1.16 language features only, but this may be limiting, and may still be problematic when (e.g.) matching signatures of dependencies.
There is an escape hatch: adding a
//go:builddirective to files that make use of go language features. From the [go toolchain docs][2]:This patch adds
//go:builddirectives to those files using recent additions to the language. It's currently using go1.19 as version to match the version in our "vendor.mod", but we can consider being more permissive ("any" requires go1.18 or up), or more "optimistic" (force go1.21, which is the version we currently use to build).For completeness sake, note that any file without a
//go:builddirective will continue to use go1.16 language version when used as a module.[1]: https://github.com/golang/go/blob/58c28ba286dd0e98fe4cca80f5d64bbcb824a685/src/cmd/go/internal/gover/version.go#L9-L56 [2]; https://go.dev/doc/toolchain#:~:text=The%20go%20line%20for,file%20to%20Go%201.22
(cherry picked from commit 70216b6)
- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)