9
9
"crypto/sha256"
10
10
"fmt"
11
11
"go/ast"
12
+ "go/build"
12
13
"go/parser"
13
14
"go/token"
14
15
"go/types"
@@ -29,6 +30,7 @@ import (
29
30
"golang.org/x/tools/gopls/internal/protocol"
30
31
"golang.org/x/tools/gopls/internal/util/bug"
31
32
"golang.org/x/tools/gopls/internal/util/safetoken"
33
+ "golang.org/x/tools/gopls/internal/util/slices"
32
34
"golang.org/x/tools/internal/analysisinternal"
33
35
"golang.org/x/tools/internal/event"
34
36
"golang.org/x/tools/internal/event/tag"
@@ -1628,10 +1630,19 @@ func (b *typeCheckBatch) typesConfig(ctx context.Context, inputs typeCheckInputs
1628
1630
1629
1631
if inputs .goVersion != "" {
1630
1632
goVersion := "go" + inputs .goVersion
1633
+
1631
1634
// types.NewChecker panics if GoVersion is invalid. An unparsable mod
1632
1635
// file should probably stop us before we get here, but double check
1633
1636
// just in case.
1634
- if goVersionRx .MatchString (goVersion ) {
1637
+ //
1638
+ // Prior to go/[email protected] the precondition was stricter:
1639
+ // no patch version. That's not a problem when also using go1.20 list,
1640
+ // as it would reject go.mod files containing a patch version, but
1641
+ // go/[email protected] will panic on go.mod versions that are returned
1642
+ // by go1.21 list, hence the need for the extra check.
1643
+ if goVersionRx .MatchString (goVersion ) &&
1644
+ (slices .Contains (build .Default .ReleaseTags , "go1.21" ) ||
1645
+ strings .Count (goVersion , "." ) < 2 ) { // no patch version
1635
1646
typesinternal .SetGoVersion (cfg , goVersion )
1636
1647
}
1637
1648
}
0 commit comments