go/analysis/passes/stdversion: reenable tests

Enable units tests after 1.23. Tests were rewritten for the changes
to the 1.21 file version event horizon.

The test is not enabled for 1.22. A backport for golang/go#68658 may be required.

For golang/go#68658

Change-Id: I15f46e3ff3de7c02592d5a357ae199116323c29f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/615685
Reviewed-by: Alan Donovan <adonovan@google.com>
Commit-Queue: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/go/analysis/passes/stdversion/stdversion_test.go b/go/analysis/passes/stdversion/stdversion_test.go
index cee6360..71dc1de 100644
--- a/go/analysis/passes/stdversion/stdversion_test.go
+++ b/go/analysis/passes/stdversion/stdversion_test.go
@@ -10,17 +10,22 @@
 
 	"golang.org/x/tools/go/analysis/analysistest"
 	"golang.org/x/tools/go/analysis/passes/stdversion"
+	"golang.org/x/tools/internal/testenv"
 	"golang.org/x/tools/internal/testfiles"
 )
 
 func Test(t *testing.T) {
-	t.Skip("Disabled for golang.org/cl/603895. Fix and re-enable.")
+	testenv.NeedsGo1Point(t, 23) // TODO(#68658): Waiting on 1.22 backport.
+
 	// The test relies on go1.21 std symbols, but the analyzer
 	// itself requires the go1.22 implementation of versions.FileVersions.
 	dir := testfiles.ExtractTxtarFileToTmp(t, filepath.Join(analysistest.TestData(), "test.txtar"))
 	analysistest.Run(t, dir, stdversion.Analyzer,
-		"example.com/a",
-		"example.com/sub",
-		"example.com/sub20",
-		"example.com/old")
+		"example.com/basic",
+		"example.com/despite",
+		"example.com/mod20",
+		"example.com/mod21",
+		"example.com/mod22",
+		"example.com/old",
+	)
 }
diff --git a/go/analysis/passes/stdversion/testdata/test.txtar b/go/analysis/passes/stdversion/testdata/test.txtar
index 0d27f11..cb04407 100644
--- a/go/analysis/passes/stdversion/testdata/test.txtar
+++ b/go/analysis/passes/stdversion/testdata/test.txtar
@@ -2,18 +2,17 @@
 
 This test references go1.21 and go1.22 symbols from std.
 
-It uses a txtar file due to golang/go#37054.
-
 See also gopls/internal/test/marker/testdata/diagnostics/stdversion.txt
 which runs the same test within the gopls analysis driver, to ensure
 coverage of per-file Go version support.
 
 -- go.work --
-go 1.21
+go 1.22
 
 use .
-use sub
-use sub20
+use mod20
+use mod21
+use mod22
 use old
 
 -- go.mod --
@@ -21,8 +20,9 @@
 
 go 1.21
 
--- a/a.go --
-package a
+-- basic/basic.go --
+// File version is 1.21.
+package basic
 
 import "go/types"
 
@@ -43,102 +43,47 @@
 	a.Underlying() // no diagnostic
 }
 
--- sub/go.mod --
-module example.com/sub
+-- despite/errors.go --
+// File version is 1.21.
 
-go 1.21
-
--- sub/sub.go --
-package sub
+// Check that RunDespiteErrors is enabled.
+package ignore
 
 import "go/types"
 
 func _() {
-	// old package-level type
-	var _ types.Info // ok: defined by go1.0
-
-	// new field of older type
+	// report something before the syntax error.
 	_ = new(types.Info).FileVersions // want `types.FileVersions requires go1.22 or later \(module is go1.21\)`
-
-	// new method of older type
-	new(types.Info).PkgNameOf // want `types.PkgNameOf requires go1.22 or later \(module is go1.21\)`
-
-	// new package-level type
-	var a types.Alias // want `types.Alias requires go1.22 or later \(module is go1.21\)`
-
-	// new method of new type
-	a.Underlying() // no diagnostic
 }
 
 invalid syntax // exercise RunDespiteErrors
 
--- sub/tagged.go --
-//go:build go1.22
+-- mod20/go.mod --
+module example.com/mod20
 
-package sub
+go 1.20
+
+-- mod20/notag.go --
+// The 1.20 module is before the forward compatibility regime:
+// The file's build tag effects selection, but
+// not language semantics, so stdversion is silent.
+
+package mod20
 
 import "go/types"
 
 func _() {
-	// old package-level type
-	var _ types.Info
-
-	// new field of older type
-	_ = new(types.Info).FileVersions
-
-	// new method of older type
-	new(types.Info).PkgNameOf
-
-	// new package-level type
-	var a types.Alias
-
-	// new method of new type
-	a.Underlying()
+	var _ types.Alias
 }
 
--- old/go.mod --
-module example.com/old
-
-go 1.5
-
--- old/old.go --
-package old
-
-import "go/types"
-
-var _ types.Alias // no diagnostic: go.mod is too old for us to care
-
--- sub/oldtagged.go --
-// The file Go version (1.16) overrides the go.mod Go version (1.21),
-// even when this means a downgrade (#67123).
-// (stdversion is silent for go.mod versions before 1.21:
-// before the forward compatibility regime, the meaning
-// of the go.mod version was not clearly defined.)
-
-//go:build go1.16
-
-package sub
-
-import "bytes"
-import "go/types"
-
-var _ = bytes.Clone // want `bytes.Clone requires go1.20 or later \(file is go1.16\)`
-var _ = types.Alias // want `types.Alias requires go1.22 or later \(file is go1.16\)`
-
--- sub20/go.mod --
-module example.com/sub20
-
-go 1.20
-
--- sub20/oldtagged.go --
-// Same test again, but with a go1.20 mod,
-// before the forward compatibility regime:
+-- mod20/tag16.go --
+// The 1.20 module is before the forward compatibility regime:
 // The file's build tag effects selection, but
 // not language semantics, so stdversion is silent.
 
 //go:build go1.16
 
-package sub
+package mod20
 
 import "bytes"
 import "go/types"
@@ -146,3 +91,134 @@
 var _ = bytes.Clone
 var _ = types.Alias
 
+-- mod20/tag22.go --
+// The 1.20 module is before the forward compatibility regime:
+// The file's build tag effects selection, but
+// not language semantics, so stdversion is silent.
+
+//go:build go1.22
+
+package mod20
+
+import "bytes"
+import "go/types"
+
+var _ = bytes.Clone
+var _ = types.Alias
+
+-- mod21/go.mod --
+module example.com/mod21
+
+go 1.21
+
+-- mod21/notag.go --
+// File version is 1.21.
+package mod21
+
+import "go/types"
+
+func _() {
+	// old package-level type
+	var _ types.Info // ok: defined by go1.0
+
+	// new field of older type
+	_ = new(types.Info).FileVersions // want `types.FileVersions requires go1.22 or later \(module is go1.21\)`
+
+	// new method of older type
+	new(types.Info).PkgNameOf // want `types.PkgNameOf requires go1.22 or later \(module is go1.21\)`
+
+	// new package-level type
+	var a types.Alias // want `types.Alias requires go1.22 or later \(module is go1.21\)`
+
+	// new method of new type
+	a.Underlying() // no diagnostic
+}
+
+-- mod21/tag16.go --
+// File version is 1.21.
+//
+// The module is within the forward compatibility regime so
+// the build tag (1.16) can modify the file version, but it cannot
+// go below the 1.21 "event horizon" (#68658).
+
+//go:build go1.16
+
+package mod21
+
+import "bytes"
+import "go/types"
+
+var _ = bytes.Clone
+var _ = types.Alias // want `types.Alias requires go1.22 or later \(module is go1.21\)`
+
+-- mod21/tag22.go --
+// File version is 1.22.
+//
+// The module is within the forward compatibility regime so
+// the build tag (1.22) updates the file version to 1.22.
+
+//go:build go1.22
+
+package mod21
+
+import "bytes"
+import "go/types"
+
+var _ = bytes.Clone
+var _ = types.Alias 
+
+-- mod22/go.mod --
+module example.com/mod22
+
+go 1.22
+
+-- mod22/notag.go --
+// File version is 1.22.
+package mod22
+
+import "go/types"
+
+func _() {
+	var _ = bytes.Clone
+	var _ = types.Alias
+}
+
+-- mod22/tag16.go --
+// File version is 1.21.
+//
+// The module is within the forward compatibility regime so
+// the build tag (1.16) can modify the file version, but it cannot
+// go below the 1.21 "event horizon" (#68658).
+
+//go:build go1.16
+
+package mod22
+
+import "bytes"
+import "go/types"
+
+var _ = bytes.Clone
+var _ = types.Alias // want `types.Alias requires go1.22 or later \(file is go1.21\)`
+
+-- old/go.mod --
+module example.com/old
+
+go 1.5
+
+-- old/notag.go --
+package old
+
+import "go/types"
+
+var _ types.Alias // no diagnostic: go.mod is too old for us to care
+
+-- old/tag21.go --
+// The build tag is ignored due to the module version.
+
+//go:build go1.21
+
+package old
+
+import "go/types"
+
+var _ = types.Alias // no diagnostic: go.mod is too old for us to care