cmd/go: definition of "go" directive in go.mod conflicts between //go:build proposal and other uses #46201
Labels
Documentation
FrozenDueToAge
GoCommand
cmd/go
modules
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
The first definition of the
go
directive ingo.mod
is that the version listed version makes a specific set of features available to the module being used. This is consistent with its use to enable//go:embed
(#44557 allowed this), lazy loading (#36460), and various other language features. I saw this first well-explained via https://twitter.com/_myitcv/status/1391819772992659461.Recent CLs have bumped all of the
x/*
modules up to state 1.17, e.g. CL 315570 with the statement:Under this definition, it's legal for a module to support versions below what is listed in
go.mod
, so long as the code is properly guarded by build tags or similar. The Go toolchain itself restricts a set of packages to build with 1.4+, even thoughgo.mod
always mirrors the current Go version. Other external packages likegolang-migrate
can safely supportio/fs
andembed
thanks to build tags.The second definition of the
go
directive ingo.mod
comes from the new//go:build
changes (#41184), specifically in the transition section of the proposal for "Go 1.(N+1)" (i.e. Go 1.18)This definition explicitly conflicts with the first, as it exactly says that the
go
directive indicates the minimum version supported by a module, and therefore it's safe to start removing things that would be required for older versions to be supported. This proposal is especially interesting, as it is changing build tags themselves, so therefore cannot be protected by build tags.While at the moment, I'm not sure that the
//go:build
changes will cause issues, if "N" in the proposal had instead meant that Go 1.17 was the version at which// +build
lines started to be removed, then the two would have clashed, and any preemptivego
directive bumping would have caused compatibility issues; future changes may not be as lucky with this as precedent. And, as modules move theirgo
version up per definition 1) to obtain new features, trusting that they can still run with older versions of Go, I can see this becoming more of a problem.Can there be some agreement on what the
go
directive actually implies, such that there isn't a conflict here? Or, is the definition used in//go:build
spec an oversight?There might be an issue for this ("what does the go directive mean") already, but I couldn't find it.
The text was updated successfully, but these errors were encountered: