]> Cypherpunks repositories - gostls13.git/commitdiff
vendor/golang.org/x/tools: update to v0.24.1-0.20240904143311-70f56264139c
authorAlan Donovan <adonovan@google.com>
Wed, 4 Sep 2024 16:24:55 +0000 (12:24 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 4 Sep 2024 20:42:05 +0000 (20:42 +0000)
Among other things, this should fix a regression in printf
whereby materialized aliases caused "any" and "interface{}"
in printf signatures not to be recognized as identical.

It also updates ureader.go used by vendored x/tools during
some tests, including cmd/internal/moddeps.TestAllDependencies.
This test uses golang.org/x/tools/cmd/bundle which uses x/reader.

Fixes #68796

Change-Id: I9f0711e66a5c4daaffe695c515aea3b8fb3d01e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/610736
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

18 files changed:
src/cmd/go.mod
src/cmd/go.sum
src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock/copylock.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/doc.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases.go
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go
src/cmd/vendor/golang.org/x/tools/internal/stdlib/manifest.go
src/cmd/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
src/cmd/vendor/golang.org/x/tools/internal/versions/constraint.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/tools/internal/versions/constraint_go121.go [new file with mode: 0644]
src/cmd/vendor/modules.txt

index 7e8860c5b44dd589cd4783e7201efbd7694ce671..88156e2bc3f150c3d2de5ff253a04cd98f0aec63 100644 (file)
@@ -11,7 +11,7 @@ require (
        golang.org/x/sys v0.23.0
        golang.org/x/telemetry v0.0.0-20240828202201-a797f331ea97
        golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292
-       golang.org/x/tools v0.23.1-0.20240722161640-ec1a81bfec7c
+       golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c
 )
 
 require (
index fff1e51f80d0017bf1e2a76175d81e607f176de8..d506614388ae7a8388b85e652f461685dfd15942 100644 (file)
@@ -22,7 +22,7 @@ golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292 h1:BOrQi08eIX3cDgGcMgFON
 golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
 golang.org/x/text v0.16.1-0.20240716160804-ae0cf96bbcd9 h1:MlCLrwVF1WvXT14xTzwuKN3u4LpUve8sG/gJUCuBpe8=
 golang.org/x/text v0.16.1-0.20240716160804-ae0cf96bbcd9/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
-golang.org/x/tools v0.23.1-0.20240722161640-ec1a81bfec7c h1:jGHQpjWnvPa5qmjhxUYeut+TlRYWRGaMcOnAZ4S5IOo=
-golang.org/x/tools v0.23.1-0.20240722161640-ec1a81bfec7c/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
+golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c h1:JImdv91aqIPqamNg5sOTUjNQD++5KkvchZi2BcYlNoE=
+golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c/go.mod h1:IV2Kidsnn7A8K7hHxn/wcUfHXkViw0LLHdu8LnpT8LU=
 rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef h1:mqLYrXCXYEZOop9/Dbo6RPX11539nwiCNBb1icVPmw8=
 rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ=
index ad27c27d1de0bf9de729927d2feba875dffbadfe..aa02eeda680ffc3c9663ac26390403d2dd4d54e0 100644 (file)
@@ -100,6 +100,8 @@ type Pass struct {
        TypesSizes   types.Sizes    // function for computing sizes of types
        TypeErrors   []types.Error  // type errors (only if Analyzer.RunDespiteErrors)
 
+       Module *Module // the package's enclosing module (possibly nil in some drivers)
+
        // Report reports a Diagnostic, a finding about a specific location
        // in the analyzed source code such as a potential mistake.
        // It may be called by the Run function.
@@ -238,3 +240,10 @@ func (pass *Pass) String() string {
 type Fact interface {
        AFact() // dummy method to avoid type errors
 }
+
+// A Module describes the module to which a package belongs.
+type Module struct {
+       Path      string // module path
+       Version   string // module version ("" if unknown, such as for workspace modules)
+       GoVersion string // go version used in module (e.g. "go1.22.0")
+}
index 5b4cf9d9edcdd4d831075ab9ba2ab6a323374977..b5a2d2775f49af9764be2f90e0b8ceb9f47bae1e 100644 (file)
@@ -15,6 +15,7 @@ import (
 
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
+       "golang.org/x/tools/internal/versions"
 )
 
 const Doc = "check //go:build and // +build directives"
@@ -264,6 +265,8 @@ func (check *checker) goBuildLine(pos token.Pos, line string) {
                return
        }
 
+       check.tags(pos, x)
+
        if check.goBuild == nil {
                check.goBuild = x
        }
@@ -323,6 +326,8 @@ func (check *checker) plusBuildLine(pos token.Pos, line string) {
                        check.crossCheck = false
                        return
                }
+               check.tags(pos, y)
+
                if check.plusBuild == nil {
                        check.plusBuild = y
                } else {
@@ -363,3 +368,51 @@ func (check *checker) finish() {
                return
        }
 }
+
+// tags reports issues in go versions in tags within the expression e.
+func (check *checker) tags(pos token.Pos, e constraint.Expr) {
+       // Check that constraint.GoVersion is meaningful (>= go1.21).
+       if versions.ConstraintGoVersion == nil {
+               return
+       }
+
+       // Use Eval to visit each tag.
+       _ = e.Eval(func(tag string) bool {
+               if malformedGoTag(tag) {
+                       check.pass.Reportf(pos, "invalid go version %q in build constraint", tag)
+               }
+               return false // result is immaterial as Eval does not short-circuit
+       })
+}
+
+// malformedGoTag returns true if a tag is likely to be a malformed
+// go version constraint.
+func malformedGoTag(tag string) bool {
+       // Not a go version?
+       if !strings.HasPrefix(tag, "go1") {
+               // Check for close misspellings of the "go1." prefix.
+               for _, pre := range []string{"go.", "g1.", "go"} {
+                       suffix := strings.TrimPrefix(tag, pre)
+                       if suffix != tag {
+                               if valid, ok := validTag("go1." + suffix); ok && valid {
+                                       return true
+                               }
+                       }
+               }
+               return false
+       }
+
+       // The tag starts with "go1" so it is almost certainly a GoVersion.
+       // Report it if it is not a valid build constraint.
+       valid, ok := validTag(tag)
+       return ok && !valid
+}
+
+// validTag returns (valid, ok) where valid reports when a tag is valid,
+// and ok reports determining if the tag is valid succeeded.
+func validTag(tag string) (valid bool, ok bool) {
+       if versions.ConstraintGoVersion != nil {
+               return versions.ConstraintGoVersion(&constraint.TagExpr{Tag: tag}) != "", true
+       }
+       return false, false
+}
index 8f6e7db6a272f34799a24f972d2190fbf36017fc..0d63cd16124c7c6516f8b108d333c8d79f0904b4 100644 (file)
@@ -20,6 +20,7 @@ import (
        "golang.org/x/tools/go/ast/inspector"
        "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
+       "golang.org/x/tools/internal/versions"
 )
 
 const Doc = `check for locks erroneously passed by value
@@ -40,18 +41,25 @@ var Analyzer = &analysis.Analyzer{
 func run(pass *analysis.Pass) (interface{}, error) {
        inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
 
+       var goversion string // effective file version ("" => unknown)
        nodeFilter := []ast.Node{
                (*ast.AssignStmt)(nil),
                (*ast.CallExpr)(nil),
                (*ast.CompositeLit)(nil),
+               (*ast.File)(nil),
                (*ast.FuncDecl)(nil),
                (*ast.FuncLit)(nil),
                (*ast.GenDecl)(nil),
                (*ast.RangeStmt)(nil),
                (*ast.ReturnStmt)(nil),
        }
-       inspect.Preorder(nodeFilter, func(node ast.Node) {
+       inspect.WithStack(nodeFilter, func(node ast.Node, push bool, stack []ast.Node) bool {
+               if !push {
+                       return false
+               }
                switch node := node.(type) {
+               case *ast.File:
+                       goversion = versions.FileVersion(pass.TypesInfo, node)
                case *ast.RangeStmt:
                        checkCopyLocksRange(pass, node)
                case *ast.FuncDecl:
@@ -61,7 +69,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
                case *ast.CallExpr:
                        checkCopyLocksCallExpr(pass, node)
                case *ast.AssignStmt:
-                       checkCopyLocksAssign(pass, node)
+                       checkCopyLocksAssign(pass, node, goversion, parent(stack))
                case *ast.GenDecl:
                        checkCopyLocksGenDecl(pass, node)
                case *ast.CompositeLit:
@@ -69,16 +77,36 @@ func run(pass *analysis.Pass) (interface{}, error) {
                case *ast.ReturnStmt:
                        checkCopyLocksReturnStmt(pass, node)
                }
+               return true
        })
        return nil, nil
 }
 
 // checkCopyLocksAssign checks whether an assignment
 // copies a lock.
-func checkCopyLocksAssign(pass *analysis.Pass, as *ast.AssignStmt) {
-       for i, x := range as.Rhs {
+func checkCopyLocksAssign(pass *analysis.Pass, assign *ast.AssignStmt, goversion string, parent ast.Node) {
+       lhs := assign.Lhs
+       for i, x := range assign.Rhs {
                if path := lockPathRhs(pass, x); path != nil {
-                       pass.ReportRangef(x, "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path)
+                       pass.ReportRangef(x, "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, assign.Lhs[i]), path)
+                       lhs = nil // An lhs has been reported. We prefer the assignment warning and do not report twice.
+               }
+       }
+
+       // After GoVersion 1.22, loop variables are implicitly copied on each iteration.
+       // So a for statement may inadvertently copy a lock when any of the
+       // iteration variables contain locks.
+       if assign.Tok == token.DEFINE && versions.AtLeast(goversion, versions.Go1_22) {
+               if parent, _ := parent.(*ast.ForStmt); parent != nil && parent.Init == assign {
+                       for _, l := range lhs {
+                               if id, ok := l.(*ast.Ident); ok && id.Name != "_" {
+                                       if obj := pass.TypesInfo.Defs[id]; obj != nil && obj.Type() != nil {
+                                               if path := lockPath(pass.Pkg, obj.Type(), nil); path != nil {
+                                                       pass.ReportRangef(l, "for loop iteration copies lock value to %v: %v", analysisutil.Format(pass.Fset, l), path)
+                                               }
+                                       }
+                               }
+                       }
                }
        }
 }
@@ -340,6 +368,14 @@ func lockPath(tpkg *types.Package, typ types.Type, seen map[types.Type]bool) typ
        return nil
 }
 
+// parent returns the second from the last node on stack if it exists.
+func parent(stack []ast.Node) ast.Node {
+       if len(stack) >= 2 {
+               return stack[len(stack)-2]
+       }
+       return nil
+}
+
 var lockerType *types.Interface
 
 // Construct a sync.Locker interface type.
index 85da8346f752eb48c1769c9f236472f0860fe193..eebf40208d18165ca14719730a77baa6ae8648ff 100644 (file)
 //
 //     log.Print("%d", 123) // log.Print call has possible formatting directive %d
 //
+// Conversely, it also reports calls to Printf-like functions with a
+// non-constant format string and no other arguments:
+//
+//     fmt.Printf(message) // non-constant format string in call to fmt.Printf
+//
+// Such calls may have been intended for the function's Print-like
+// counterpart: if the value of message happens to contain "%",
+// misformatting will occur. In this case, the checker additionally
+// suggests a fix to turn the call into:
+//
+//     fmt.Printf("%s", message)
+//
 // # Inferred printf wrappers
 //
 // Functions that delegate their arguments to fmt.Printf are
index 323501925832e29a7cf614b9bbc1e19654db6d18..c548cb1c1dca93fc8a5d0faf6930bcccc76ce447 100644 (file)
@@ -159,10 +159,11 @@ func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper {
        params := sig.Params()
        nparams := params.Len() // variadic => nonzero
 
+       // Check final parameter is "args ...interface{}".
        args := params.At(nparams - 1)
-       iface, ok := args.Type().(*types.Slice).Elem().(*types.Interface)
+       iface, ok := aliases.Unalias(args.Type().(*types.Slice).Elem()).(*types.Interface)
        if !ok || !iface.Empty() {
-               return nil // final (args) param is not ...interface{}
+               return nil
        }
 
        // Is second last param 'format string'?
@@ -372,64 +373,29 @@ var isPrint = stringSet{
        "(testing.TB).Skipf":  true,
 }
 
-// formatString returns the format string argument and its index within
-// the given printf-like call expression.
-//
-// The last parameter before variadic arguments is assumed to be
-// a format string.
-//
-// The first string literal or string constant is assumed to be a format string
-// if the call's signature cannot be determined.
-//
-// If it cannot find any format string parameter, it returns ("", -1).
-func formatString(pass *analysis.Pass, call *ast.CallExpr) (format string, idx int) {
+// formatStringIndex returns the index of the format string (the last
+// non-variadic parameter) within the given printf-like call
+// expression, or -1 if unknown.
+func formatStringIndex(pass *analysis.Pass, call *ast.CallExpr) int {
        typ := pass.TypesInfo.Types[call.Fun].Type
-       if typ != nil {
-               if sig, ok := typ.(*types.Signature); ok {
-                       if !sig.Variadic() {
-                               // Skip checking non-variadic functions.
-                               return "", -1
-                       }
-                       idx := sig.Params().Len() - 2
-                       if idx < 0 {
-                               // Skip checking variadic functions without
-                               // fixed arguments.
-                               return "", -1
-                       }
-                       s, ok := stringConstantArg(pass, call, idx)
-                       if !ok {
-                               // The last argument before variadic args isn't a string.
-                               return "", -1
-                       }
-                       return s, idx
-               }
+       if typ == nil {
+               return -1 // missing type
        }
-
-       // Cannot determine call's signature. Fall back to scanning for the first
-       // string constant in the call.
-       for idx := range call.Args {
-               if s, ok := stringConstantArg(pass, call, idx); ok {
-                       return s, idx
-               }
-               if pass.TypesInfo.Types[call.Args[idx]].Type == types.Typ[types.String] {
-                       // Skip checking a call with a non-constant format
-                       // string argument, since its contents are unavailable
-                       // for validation.
-                       return "", -1
-               }
+       sig, ok := typ.(*types.Signature)
+       if !ok {
+               return -1 // ill-typed
        }
-       return "", -1
-}
-
-// stringConstantArg returns call's string constant argument at the index idx.
-//
-// ("", false) is returned if call's argument at the index idx isn't a string
-// constant.
-func stringConstantArg(pass *analysis.Pass, call *ast.CallExpr, idx int) (string, bool) {
-       if idx >= len(call.Args) {
-               return "", false
+       if !sig.Variadic() {
+               // Skip checking non-variadic functions.
+               return -1
        }
-       return stringConstantExpr(pass, call.Args[idx])
+       idx := sig.Params().Len() - 2
+       if idx < 0 {
+               // Skip checking variadic functions without
+               // fixed arguments.
+               return -1
+       }
+       return idx
 }
 
 // stringConstantExpr returns expression's string constant value.
@@ -536,10 +502,34 @@ type formatState struct {
 
 // checkPrintf checks a call to a formatted print routine such as Printf.
 func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, fn *types.Func) {
-       format, idx := formatString(pass, call)
-       if idx < 0 {
-               if false {
-                       pass.Reportf(call.Lparen, "can't check non-constant format in call to %s", fn.FullName())
+       idx := formatStringIndex(pass, call)
+       if idx < 0 || idx >= len(call.Args) {
+               return
+       }
+       formatArg := call.Args[idx]
+       format, ok := stringConstantExpr(pass, formatArg)
+       if !ok {
+               // Format string argument is non-constant.
+
+               // It is a common mistake to call fmt.Printf(msg) with a
+               // non-constant format string and no arguments:
+               // if msg contains "%", misformatting occurs.
+               // Report the problem and suggest a fix: fmt.Printf("%s", msg).
+               if idx == len(call.Args)-1 {
+                       pass.Report(analysis.Diagnostic{
+                               Pos: formatArg.Pos(),
+                               End: formatArg.End(),
+                               Message: fmt.Sprintf("non-constant format string in call to %s",
+                                       fn.FullName()),
+                               SuggestedFixes: []analysis.SuggestedFix{{
+                                       Message: `Insert "%s" format string`,
+                                       TextEdits: []analysis.TextEdit{{
+                                               Pos:     formatArg.Pos(),
+                                               End:     formatArg.Pos(),
+                                               NewText: []byte(`"%s", `),
+                                       }},
+                               }},
+                       })
                }
                return
        }
index f5e760ca265e4c5b9789d0d214e691765073b924..5b4598235cfa1a16433680b50c91a11fafd6cb82 100644 (file)
@@ -6,7 +6,6 @@ package tests
 
 import (
        _ "embed"
-       "fmt"
        "go/ast"
        "go/token"
        "go/types"
@@ -184,13 +183,13 @@ func checkAddCalls(pass *analysis.Pass, fn *ast.FuncDecl, params *types.Tuple) {
                                i := mismatched[0]
                                expr := call.Args[i]
                                t := pass.TypesInfo.Types[expr].Type
-                               pass.ReportRangef(expr, fmt.Sprintf("mismatched type in call to (*testing.F).Add: %v, fuzz target expects %v", t, params.At(i+1).Type()))
+                               pass.ReportRangef(expr, "mismatched type in call to (*testing.F).Add: %v, fuzz target expects %v", t, params.At(i+1).Type())
                        } else if len(mismatched) > 1 {
                                var gotArgs, wantArgs []types.Type
                                for i := 0; i < len(call.Args); i++ {
                                        gotArgs, wantArgs = append(gotArgs, pass.TypesInfo.Types[call.Args[i]].Type), append(wantArgs, params.At(i+1).Type())
                                }
-                               pass.ReportRangef(call, fmt.Sprintf("mismatched types in call to (*testing.F).Add: %v, fuzz target expects %v", gotArgs, wantArgs))
+                               pass.ReportRangef(call, "mismatched types in call to (*testing.F).Add: %v, fuzz target expects %v", gotArgs, wantArgs)
                        }
                }
                return true
@@ -244,7 +243,7 @@ func validateFuzzArgs(pass *analysis.Pass, params *types.Tuple, expr ast.Expr) b
                                        }
                                }
                        }
-                       pass.ReportRangef(exprRange, "fuzzing arguments can only have the following types: "+formatAcceptedFuzzType())
+                       pass.ReportRangef(exprRange, "fuzzing arguments can only have the following types: %s", formatAcceptedFuzzType())
                        ok = false
                }
        }
index d77fb203d85f89e8ec7c9de988c5c7438e77b157..71ebbfaef1586b25e18bb0560fd8f699c3c2be0b 100644 (file)
@@ -66,6 +66,8 @@ type Config struct {
        GoFiles                   []string
        NonGoFiles                []string
        IgnoredFiles              []string
+       ModulePath                string            // module path
+       ModuleVersion             string            // module version
        ImportMap                 map[string]string // maps import path to package path
        PackageFile               map[string]string // maps package path to file of type information
        Standard                  map[string]bool   // package belongs to standard library
@@ -359,6 +361,12 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
                                factFilter[reflect.TypeOf(f)] = true
                        }
 
+                       module := &analysis.Module{
+                               Path:      cfg.ModulePath,
+                               Version:   cfg.ModuleVersion,
+                               GoVersion: cfg.GoVersion,
+                       }
+
                        pass := &analysis.Pass{
                                Analyzer:          a,
                                Fset:              fset,
@@ -377,6 +385,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
                                ImportPackageFact: facts.ImportPackageFact,
                                ExportPackageFact: facts.ExportPackageFact,
                                AllPackageFacts:   func() []analysis.PackageFact { return facts.AllPackageFacts(factFilter) },
+                               Module:            module,
                        }
                        pass.ReadFile = analysisinternal.MakeReadFile(pass)
 
index d648c3d071b00e9a80b1452226fbf4792556ce79..9ada177758ff7308c171da582ff6a00af2a00d1a 100644 (file)
@@ -51,7 +51,7 @@ type Path string
 //
 //     PO package->object      Package.Scope.Lookup
 //     OT  object->type        Object.Type
-//     TT    type->type        Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying} [EKPRUTrC]
+//     TT    type->type        Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa]
 //     TO   type->object       Type.{At,Field,Method,Obj} [AFMO]
 //
 // All valid paths start with a package and end at an object
@@ -63,7 +63,7 @@ type Path string
 //   - The only PO operator is Package.Scope.Lookup, which requires an identifier.
 //   - The only OT operator is Object.Type,
 //     which we encode as '.' because dot cannot appear in an identifier.
-//   - The TT operators are encoded as [EKPRUTrC];
+//   - The TT operators are encoded as [EKPRUTrCa];
 //     two of these ({,Recv}TypeParams) require an integer operand,
 //     which is encoded as a string of decimal digits.
 //   - The TO operators are encoded as [AFMO];
@@ -106,6 +106,7 @@ const (
        opTypeParam     = 'T' // .TypeParams.At(i)      (Named, Signature)
        opRecvTypeParam = 'r' // .RecvTypeParams.At(i)  (Signature)
        opConstraint    = 'C' // .Constraint()          (TypeParam)
+       opRhs           = 'a' // .Rhs()                 (Alias)
 
        // type->object operators
        opAt     = 'A' // .At(i)        (Tuple)
@@ -279,21 +280,26 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
                path = append(path, opType)
 
                T := o.Type()
+               if alias, ok := T.(*aliases.Alias); ok {
+                       if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam, nil); r != nil {
+                               return Path(r), nil
+                       }
+                       if r := find(obj, aliases.Rhs(alias), append(path, opRhs), nil); r != nil {
+                               return Path(r), nil
+                       }
 
-               if tname.IsAlias() {
-                       // type alias
+               } else if tname.IsAlias() {
+                       // legacy alias
                        if r := find(obj, T, path, nil); r != nil {
                                return Path(r), nil
                        }
-               } else {
-                       if named, _ := T.(*types.Named); named != nil {
-                               if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam, nil); r != nil {
-                                       // generic named type
-                                       return Path(r), nil
-                               }
-                       }
+
+               } else if named, ok := T.(*types.Named); ok {
                        // defined (named) type
-                       if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil {
+                       if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam, nil); r != nil {
+                               return Path(r), nil
+                       }
+                       if r := find(obj, named.Underlying(), append(path, opUnderlying), nil); r != nil {
                                return Path(r), nil
                        }
                }
@@ -657,6 +663,16 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
                        }
                        t = named.Underlying()
 
+               case opRhs:
+                       if alias, ok := t.(*aliases.Alias); ok {
+                               t = aliases.Rhs(alias)
+                       } else if false && aliases.Enabled() {
+                               // The Enabled check is too expensive, so for now we
+                               // simply assume that aliases are not enabled.
+                               // TODO(adonovan): replace with "if true {" when go1.24 is assured.
+                               return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t)
+                       }
+
                case opTypeParam:
                        hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
                        if !ok {
index c24c2eee457f2e2dc1fcf6daa337bed2ed4cba9c..f7798e3354e485cc108abb46c6d5fd2ea7680396 100644 (file)
@@ -22,11 +22,17 @@ import (
 // GODEBUG=gotypesalias=... by invoking the type checker. The Enabled
 // function is expensive and should be called once per task (e.g.
 // package import), not once per call to NewAlias.
-func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
+//
+// Precondition: enabled || len(tparams)==0.
+// If materialized aliases are disabled, there must not be any type parameters.
+func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName {
        if enabled {
                tname := types.NewTypeName(pos, pkg, name, nil)
-               newAlias(tname, rhs)
+               newAlias(tname, rhs, tparams)
                return tname
        }
+       if len(tparams) > 0 {
+               panic("cannot create an alias with type parameters when gotypesalias is not enabled")
+       }
        return types.NewTypeName(pos, pkg, name, rhs)
 }
index c027b9f315f6803c1b72cfbf7d0db47724e4eeee..a775fcc4bedad930ac0f8fed1534e934f5452d55 100644 (file)
@@ -15,15 +15,21 @@ import (
 // It will never be created by go/types.
 type Alias struct{}
 
-func (*Alias) String() string         { panic("unreachable") }
-func (*Alias) Underlying() types.Type { panic("unreachable") }
-func (*Alias) Obj() *types.TypeName   { panic("unreachable") }
-func Rhs(alias *Alias) types.Type     { panic("unreachable") }
+func (*Alias) String() string                                { panic("unreachable") }
+func (*Alias) Underlying() types.Type                        { panic("unreachable") }
+func (*Alias) Obj() *types.TypeName                          { panic("unreachable") }
+func Rhs(alias *Alias) types.Type                            { panic("unreachable") }
+func TypeParams(alias *Alias) *types.TypeParamList           { panic("unreachable") }
+func SetTypeParams(alias *Alias, tparams []*types.TypeParam) { panic("unreachable") }
+func TypeArgs(alias *Alias) *types.TypeList                  { panic("unreachable") }
+func Origin(alias *Alias) *Alias                             { panic("unreachable") }
 
 // Unalias returns the type t for go <=1.21.
 func Unalias(t types.Type) types.Type { return t }
 
-func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") }
+func newAlias(name *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias {
+       panic("unreachable")
+}
 
 // Enabled reports whether [NewAlias] should create [types.Alias] types.
 //
index b32995484190af15e881214c8c94eb1154436095..31c159e42e6c44e0b22b6bc2437008e149a91656 100644 (file)
@@ -28,16 +28,51 @@ func Rhs(alias *Alias) types.Type {
        return Unalias(alias)
 }
 
+// TypeParams returns the type parameter list of the alias.
+func TypeParams(alias *Alias) *types.TypeParamList {
+       if alias, ok := any(alias).(interface{ TypeParams() *types.TypeParamList }); ok {
+               return alias.TypeParams() // go1.23+
+       }
+       return nil
+}
+
+// SetTypeParams sets the type parameters of the alias type.
+func SetTypeParams(alias *Alias, tparams []*types.TypeParam) {
+       if alias, ok := any(alias).(interface {
+               SetTypeParams(tparams []*types.TypeParam)
+       }); ok {
+               alias.SetTypeParams(tparams) // go1.23+
+       } else if len(tparams) > 0 {
+               panic("cannot set type parameters of an Alias type in go1.22")
+       }
+}
+
+// TypeArgs returns the type arguments used to instantiate the Alias type.
+func TypeArgs(alias *Alias) *types.TypeList {
+       if alias, ok := any(alias).(interface{ TypeArgs() *types.TypeList }); ok {
+               return alias.TypeArgs() // go1.23+
+       }
+       return nil // empty (go1.22)
+}
+
+// Origin returns the generic Alias type of which alias is an instance.
+// If alias is not an instance of a generic alias, Origin returns alias.
+func Origin(alias *Alias) *Alias {
+       if alias, ok := any(alias).(interface{ Origin() *types.Alias }); ok {
+               return alias.Origin() // go1.23+
+       }
+       return alias // not an instance of a generic alias (go1.22)
+}
+
 // Unalias is a wrapper of types.Unalias.
 func Unalias(t types.Type) types.Type { return types.Unalias(t) }
 
 // newAlias is an internal alias around types.NewAlias.
 // Direct usage is discouraged as the moment.
 // Try to use NewAlias instead.
-func newAlias(tname *types.TypeName, rhs types.Type) *Alias {
+func newAlias(tname *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias {
        a := types.NewAlias(tname, rhs)
-       // TODO(go.dev/issue/65455): Remove kludgy workaround to set a.actual as a side-effect.
-       Unalias(a)
+       SetTypeParams(a, tparams)
        return a
 }
 
index a928acf29facfe4415df7b6091e85462337a2b9e..cdaac9ab34df2632265636d5a5f9ad03b260d018 100644 (file)
@@ -951,7 +951,7 @@ var PackageSymbols = map[string][]Symbol{
                {"ParseSessionState", Func, 21},
                {"QUICClient", Func, 21},
                {"QUICConfig", Type, 21},
-               {"QUICConfig.EnableStoreSessionEvent", Field, 23},
+               {"QUICConfig.EnableSessionEvents", Field, 23},
                {"QUICConfig.TLSConfig", Field, 21},
                {"QUICConn", Type, 21},
                {"QUICEncryptionLevel", Type, 21},
index 834e05381ceaaf48db27dee9e2211a40ab81a7d2..131caab2847ecf86997e05a3c059f0dea9dd34a2 100644 (file)
@@ -838,7 +838,7 @@ const (
        // InvalidCap occurs when an argument to the cap built-in function is not of
        // supported type.
        //
-       // See https://golang.org/ref/spec#Lengthand_capacity for information on
+       // See https://golang.org/ref/spec#Length_and_capacity for information on
        // which underlying types are supported as arguments to cap and len.
        //
        // Example:
@@ -859,7 +859,7 @@ const (
        // InvalidCopy occurs when the arguments are not of slice type or do not
        // have compatible type.
        //
-       // See https://golang.org/ref/spec#Appendingand_copying_slices for more
+       // See https://golang.org/ref/spec#Appending_and_copying_slices for more
        // information on the type requirements for the copy built-in.
        //
        // Example:
@@ -897,7 +897,7 @@ const (
        // InvalidLen occurs when an argument to the len built-in function is not of
        // supported type.
        //
-       // See https://golang.org/ref/spec#Lengthand_capacity for information on
+       // See https://golang.org/ref/spec#Length_and_capacity for information on
        // which underlying types are supported as arguments to cap and len.
        //
        // Example:
@@ -914,7 +914,7 @@ const (
 
        // InvalidMake occurs when make is called with an unsupported type argument.
        //
-       // See https://golang.org/ref/spec#Makingslices_maps_and_channels for
+       // See https://golang.org/ref/spec#Making_slices_maps_and_channels for
        // information on the types that may be created using make.
        //
        // Example:
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/constraint.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/constraint.go
new file mode 100644 (file)
index 0000000..179063d
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package versions
+
+import "go/build/constraint"
+
+// ConstraintGoVersion is constraint.GoVersion (if built with go1.21+).
+// Otherwise nil.
+//
+// Deprecate once x/tools is after go1.21.
+var ConstraintGoVersion func(x constraint.Expr) string
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/constraint_go121.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/constraint_go121.go
new file mode 100644 (file)
index 0000000..3801140
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+// +build go1.21
+
+package versions
+
+import "go/build/constraint"
+
+func init() {
+       ConstraintGoVersion = constraint.GoVersion
+}
index 698b0255b310e225f52a9a22442ba249fa82d74b..a893906ed3021c9b512e267c9b7efb7c6ab3e6f4 100644 (file)
@@ -71,8 +71,8 @@ golang.org/x/text/internal/tag
 golang.org/x/text/language
 golang.org/x/text/transform
 golang.org/x/text/unicode/norm
-# golang.org/x/tools v0.23.1-0.20240722161640-ec1a81bfec7c
-## explicit; go 1.19
+# golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c
+## explicit; go 1.22.6
 golang.org/x/tools/cmd/bisect
 golang.org/x/tools/cover
 golang.org/x/tools/go/analysis