[gopls-release-branch.0.15] gopls/internal/cache: use language versions
when validating Go version

The check in CL 576678 was comparing the release version, which is a
language version, with the contents of the go directive, which may be a
toolchain version. As a result, gopls detects go1.22 < go1.22.2, and
does not set types.Config.GoVersion. Normally this would be acceptable,
since go/types falls back on allowing all language features.
Unfortunately, gopls@v0.15.x lacks CL 567635, and so the loopclosure
analyzer reports a diagnostic in this case.

Fix by comparing language versions.

Fixes golang/go#567635

Change-Id: I13747f19e48186105967b9c777de5ca34908545f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/579758
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Tim King <taking@google.com>
diff --git a/gopls/internal/cache/check.go b/gopls/internal/cache/check.go
index 169d8c1..9800abe 100644
--- a/gopls/internal/cache/check.go
+++ b/gopls/internal/cache/check.go
@@ -1652,7 +1652,7 @@
 		return false // malformed version string
 	}
 
-	if relVer := releaseVersion(); relVer != "" && versions.Compare(relVer, goVersion) < 0 {
+	if relVer := releaseVersion(); relVer != "" && versions.Compare(versions.Lang(relVer), versions.Lang(goVersion)) < 0 {
 		return false // 'go list' is too new for go/types
 	}
 
diff --git a/gopls/internal/test/marker/testdata/fixedbugs/issue66876.txt b/gopls/internal/test/marker/testdata/fixedbugs/issue66876.txt
new file mode 100644
index 0000000..d6edcb5
--- /dev/null
+++ b/gopls/internal/test/marker/testdata/fixedbugs/issue66876.txt
@@ -0,0 +1,27 @@
+This test checks that gopls successfully suppresses loopclosure diagnostics
+when the go.mod go version is set to a 1.22 toolchain version (1.22.x).
+
+In golang/go#66876, gopls failed to handle this correctly.
+
+-- flags --
+-min_go=go1.22
+
+-- go.mod --
+module example.com/loopclosure
+
+go 1.22.0
+
+-- p.go --
+package main
+
+var x int //@loc(x, "x")
+
+func main() {
+	// Verify that type checking actually succeeded by jumping to
+	// an arbitrary definition.
+	_ = x //@def("x", x)
+
+	for i := range 10 {
+		go func() { println(i) }()
+	}
+}