Implicits: make(map[syntax.Node]types2.Object),
Scopes: make(map[syntax.Node]*types2.Scope),
Instances: make(map[*syntax.Name]types2.Instance),
- FileVersions: make(map[*syntax.PosBase]types2.Version),
+ FileVersions: make(map[*syntax.PosBase]string),
// expand as needed
}
conf.Error = func(err error) {
for !posBase.IsFileBase() { // line directive base
posBase = posBase.Pos().Base()
}
- v := info.FileVersions[posBase]
- fileVersion := fmt.Sprintf("go%d.%d", v.Major, v.Minor)
+ fileVersion := info.FileVersions[posBase]
file := posBaseMap[posBase]
if file.GoVersion == fileVersion {
// If we have a version error caused by //go:build, report it.
"fmt"
"go/constant"
"go/token"
+ "go/version"
"internal/buildcfg"
"internal/pkgbits"
"os"
func (w *writer) distinctVars(stmt *syntax.ForStmt) bool {
lv := base.Debug.LoopVar
- v := w.p.info.FileVersions[stmt.Pos().Base()]
- is122 := v.Major == 0 && v.Minor == 0 || v.Major == 1 && v.Minor >= 22
+ fileVersion := w.p.info.FileVersions[stmt.Pos().Base()]
+ is122 := fileVersion == "" || version.Compare(fileVersion, "go1.22") >= 0
// Turning off loopvar for 1.22 is only possible with loopvarhash=qn
//
// appear in this list.
InitOrder []*Initializer
- // FileVersions maps a file's position base to the file's Go version.
- // If the file doesn't specify a version and Config.GoVersion is not
- // given, the reported version is the zero version (Major, Minor = 0, 0).
- FileVersions map[*syntax.PosBase]Version
+ // FileVersions maps a file to its Go version string.
+ // If the file doesn't specify a version, the reported
+ // string is Config.GoVersion.
+ // Version strings begin with “go”, like “go1.21”, and
+ // are suitable for use with the [go/version] package.
+ FileVersions map[*syntax.PosBase]string
}
func (info *Info) recordTypes() bool {
return buf.String()
}
-// A Version represents a released Go version.
-type Version struct {
- Major int
- Minor int
-}
-
// Check type-checks a package and returns the resulting package object and
// the first error if any. Additionally, if info != nil, Check populates each
// of the non-nil maps in the Info struct.
for _, test := range []struct {
moduleVersion string
fileVersion string
- want Version
+ wantVersion string
}{
- {"", "", Version{0, 0}}, // no versions specified
- {"go1.19", "", Version{1, 19}}, // module version specified
- {"", "go1.20", Version{0, 0}}, // file upgrade ignored
- {"go1.19", "go1.20", Version{1, 20}}, // file upgrade permitted
- {"go1.20", "go1.19", Version{1, 20}}, // file downgrade not permitted
- {"go1.21", "go1.19", Version{1, 19}}, // file downgrade permitted (module version is >= go1.21)
+ {"", "", ""}, // no versions specified
+ {"go1.19", "", "go1.19"}, // module version specified
+ {"", "go1.20", ""}, // file upgrade ignored
+ {"go1.19", "go1.20", "go1.20"}, // file upgrade permitted
+ {"go1.20", "go1.19", "go1.20"}, // file downgrade not permitted
+ {"go1.21", "go1.19", "go1.19"}, // file downgrade permitted (module version is >= go1.21)
} {
var src string
if test.fileVersion != "" {
src += "package p"
conf := Config{GoVersion: test.moduleVersion}
- versions := make(map[*syntax.PosBase]Version)
+ versions := make(map[*syntax.PosBase]string)
var info Info
info.FileVersions = versions
mustTypecheck(src, &conf, &info)
n := 0
for _, v := range info.FileVersions {
- want := test.want
- if v.Major != want.Major || v.Minor != want.Minor {
+ want := test.wantVersion
+ if v != want {
t.Errorf("%q: unexpected file version: got %v, want %v", src, v, want)
}
n++
}
for _, file := range check.files {
- fbase := base(file.Pos()) // fbase may be nil for tests
- check.recordFileVersion(fbase, check.version) // record package version (possibly zero version)
+ fbase := base(file.Pos()) // fbase may be nil for tests
+ check.recordFileVersion(fbase, check.conf.GoVersion) // record package version (possibly zero version)
v, _ := parseGoVersion(file.GoVersion)
if v.major > 0 {
if v.equal(check.version) {
check.posVers = make(map[*syntax.PosBase]version)
}
check.posVers[fbase] = v
- check.recordFileVersion(fbase, v) // overwrite package version
+ check.recordFileVersion(fbase, file.GoVersion) // overwrite package version
}
}
}
}
}
-func (check *Checker) recordFileVersion(fbase *syntax.PosBase, v version) {
+func (check *Checker) recordFileVersion(fbase *syntax.PosBase, version string) {
if m := check.FileVersions; m != nil {
- m[fbase] = Version{v.major, v.minor}
+ m[fbase] = version
}
}
// include all packages within subdirectories as well.
// These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
var bootstrapDirs = []string{
+ "cmp",
"cmd/asm",
"cmd/asm/internal/...",
"cmd/cgo",
"debug/pe",
"go/build/constraint",
"go/constant",
+ "go/version",
"internal/abi",
"internal/coverage",
"cmd/internal/cov/covcmd",
"internal/godebugs",
"internal/goexperiment",
"internal/goroot",
+ "internal/gover",
"internal/goversion",
// internal/lazyregexp is provided by Go 1.17, which permits it to
// be imported by other packages in this list, but is not provided
// collect file versions
for _, file := range check.files {
- check.recordFileVersion(file, check.conf.GoVersion)
+ check.recordFileVersion(file, check.conf.GoVersion) // record package version (possibly zero version)
if v, _ := parseGoVersion(file.GoVersion); v.major > 0 {
if v.equal(check.version) {
continue