From 35d3d2ae0f7661c8da0d8c004855a5395e95118a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 11:23:09 +0000 Subject: [PATCH] chore(deps): bump golang.org/x/tools from 0.1.9 to 0.1.10 in /tools Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.1.9 to 0.1.10. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.1.9...v0.1.10) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tools/go.mod | 4 +- tools/go.sum | 6 +- tools/vendor/golang.org/x/mod/modfile/rule.go | 250 ++++++---- tools/vendor/golang.org/x/mod/modfile/work.go | 234 ++++++++++ .../vendor/golang.org/x/mod/module/module.go | 9 +- .../vendor/golang.org/x/mod/semver/semver.go | 10 - .../go/analysis/passes/composite/whitelist.go | 9 +- .../x/tools/go/analysis/passes/tests/tests.go | 230 ++++++++++ .../x/tools/go/internal/gcimporter/iimport.go | 23 +- .../golang.org/x/tools/go/loader/loader.go | 2 + .../vendor/golang.org/x/tools/go/ssa/block.go | 118 +++++ .../golang.org/x/tools/go/ssa/builder.go | 97 ++-- .../golang.org/x/tools/go/ssa/create.go | 11 +- .../vendor/golang.org/x/tools/go/ssa/emit.go | 15 +- .../vendor/golang.org/x/tools/go/ssa/func.go | 155 ++----- .../golang.org/x/tools/go/ssa/methods.go | 2 +- .../x/tools/go/ssa/parameterized.go | 113 +++++ .../vendor/golang.org/x/tools/go/ssa/print.go | 18 +- .../golang.org/x/tools/go/ssa/sanity.go | 4 +- .../golang.org/x/tools/go/ssa/source.go | 18 +- tools/vendor/golang.org/x/tools/go/ssa/ssa.go | 16 +- .../golang.org/x/tools/go/ssa/ssautil/load.go | 2 + .../vendor/golang.org/x/tools/go/ssa/subst.go | 432 ++++++++++++++++++ .../vendor/golang.org/x/tools/go/ssa/util.go | 45 ++ .../golang.org/x/tools/go/ssa/wrappers.go | 14 +- .../x/tools/go/types/typeutil/map.go | 10 +- .../internal/analysisinternal/analysis.go | 3 + .../x/tools/internal/gocommand/invoke.go | 16 +- .../x/tools/internal/gocommand/vendor.go | 22 +- .../x/tools/internal/imports/imports.go | 2 +- .../x/tools/internal/imports/mod.go | 25 +- .../x/tools/internal/typeparams/common.go | 101 ++++ .../internal/typeparams/typeparams_go117.go | 5 + .../internal/typeparams/typeparams_go118.go | 5 + .../tools/internal/typesinternal/errorcode.go | 158 +++++++ .../typesinternal/errorcode_string.go | 18 +- .../x/tools/internal/typesinternal/types.go | 2 + .../tools/internal/typesinternal/types_118.go | 19 + tools/vendor/modules.txt | 4 +- 39 files changed, 1871 insertions(+), 356 deletions(-) create mode 100644 tools/vendor/golang.org/x/mod/modfile/work.go create mode 100644 tools/vendor/golang.org/x/tools/go/ssa/block.go create mode 100644 tools/vendor/golang.org/x/tools/go/ssa/parameterized.go create mode 100644 tools/vendor/golang.org/x/tools/go/ssa/subst.go create mode 100644 tools/vendor/golang.org/x/tools/internal/typesinternal/types_118.go diff --git a/tools/go.mod b/tools/go.mod index f4dbcea2..50cfbebf 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -9,7 +9,7 @@ require ( github.com/matm/gocov-html v0.0.0-20200509184451-71874e2e203b github.com/mattn/goveralls v0.0.11 github.com/obalunenko/coverbadger v1.1.0 - golang.org/x/tools v0.1.9 + golang.org/x/tools v0.1.10 gotest.tools/gotestsum v1.7.0 ) @@ -259,7 +259,7 @@ require ( go.opencensus.io v0.23.0 // indirect gocloud.dev v0.24.0 // indirect golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect - golang.org/x/mod v0.5.1 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect diff --git a/tools/go.sum b/tools/go.sum index 87d235ab..a67b3778 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -1356,8 +1356,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1682,8 +1683,9 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/tools/vendor/golang.org/x/mod/modfile/rule.go b/tools/vendor/golang.org/x/mod/modfile/rule.go index ca03e70e..ed2f31aa 100644 --- a/tools/vendor/golang.org/x/mod/modfile/rule.go +++ b/tools/vendor/golang.org/x/mod/modfile/rule.go @@ -423,68 +423,12 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a } case "replace": - arrow := 2 - if len(args) >= 2 && args[1] == "=>" { - arrow = 1 - } - if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { - errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - pathMajor, err := modulePathMajor(s) - if err != nil { - wrapModPathError(s, err) - return - } - var v string - if arrow == 2 { - v, err = parseVersion(verb, s, &args[1], fix) - if err != nil { - wrapError(err) - return - } - if err := module.CheckPathMajor(v, pathMajor); err != nil { - wrapModPathError(s, err) - return - } - } - ns, err := parseString(&args[arrow+1]) - if err != nil { - errorf("invalid quoted string: %v", err) + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) return } - nv := "" - if len(args) == arrow+2 { - if !IsDirectoryPath(ns) { - errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") - return - } - if filepath.Separator == '/' && strings.Contains(ns, `\`) { - errorf("replacement directory appears to be Windows path (on a non-windows system)") - return - } - } - if len(args) == arrow+3 { - nv, err = parseVersion(verb, ns, &args[arrow+2], fix) - if err != nil { - wrapError(err) - return - } - if IsDirectoryPath(ns) { - errorf("replacement module directory path %q cannot have version", ns) - return - } - } - f.Replace = append(f.Replace, &Replace{ - Old: module.Version{Path: s, Version: v}, - New: module.Version{Path: ns, Version: nv}, - Syntax: line, - }) + f.Replace = append(f.Replace, replace) case "retract": rationale := parseDirectiveComment(block, line) @@ -515,6 +459,83 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a } } +func parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) { + wrapModPathError := func(modPath string, err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + ModPath: modPath, + Verb: verb, + Err: err, + } + } + wrapError := func(err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + Err: err, + } + } + errorf := func(format string, args ...interface{}) *Error { + return wrapError(fmt.Errorf(format, args...)) + } + + arrow := 2 + if len(args) >= 2 && args[1] == "=>" { + arrow = 1 + } + if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { + return nil, errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) + } + s, err := parseString(&args[0]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + pathMajor, err := modulePathMajor(s) + if err != nil { + return nil, wrapModPathError(s, err) + + } + var v string + if arrow == 2 { + v, err = parseVersion(verb, s, &args[1], fix) + if err != nil { + return nil, wrapError(err) + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + return nil, wrapModPathError(s, err) + } + } + ns, err := parseString(&args[arrow+1]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + nv := "" + if len(args) == arrow+2 { + if !IsDirectoryPath(ns) { + return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") + } + if filepath.Separator == '/' && strings.Contains(ns, `\`) { + return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") + } + } + if len(args) == arrow+3 { + nv, err = parseVersion(verb, ns, &args[arrow+2], fix) + if err != nil { + return nil, wrapError(err) + } + if IsDirectoryPath(ns) { + return nil, errorf("replacement module directory path %q cannot have version", ns) + + } + } + return &Replace{ + Old: module.Version{Path: s, Version: v}, + New: module.Version{Path: ns, Version: nv}, + Syntax: line, + }, nil +} + // fixRetract applies fix to each retract directive in f, appending any errors // to errs. // @@ -556,6 +577,63 @@ func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) { } } +func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer) { + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + Err: err, + }) + } + errorf := func(format string, args ...interface{}) { + wrapError(fmt.Errorf(format, args...)) + } + + switch verb { + default: + errorf("unknown directive: %s", verb) + + case "go": + if f.Go != nil { + errorf("repeated go statement") + return + } + if len(args) != 1 { + errorf("go directive expects exactly one argument") + return + } else if !GoVersionRE.MatchString(args[0]) { + errorf("invalid go version '%s': must match format 1.23", args[0]) + return + } + + f.Go = &Go{Syntax: line} + f.Go.Version = args[0] + + case "use": + if len(args) != 1 { + errorf("usage: %s local/dir", verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + errorf("invalid quoted string: %v", err) + return + } + f.Use = append(f.Use, &Use{ + Path: s, + Syntax: line, + }) + + case "replace": + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) + return + } + f.Replace = append(f.Replace, replace) + } +} + // IsDirectoryPath reports whether the given path should be interpreted // as a directory path. Just like on the go command line, relative paths // and rooted paths are directory paths; the rest are module paths. @@ -1212,6 +1290,10 @@ func (f *File) DropExclude(path, vers string) error { } func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func addReplace(syntax *FileSyntax, replace *[]*Replace, oldPath, oldVers, newPath, newVers string) error { need := true old := module.Version{Path: oldPath, Version: oldVers} new := module.Version{Path: newPath, Version: newVers} @@ -1225,12 +1307,12 @@ func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { } var hint *Line - for _, r := range f.Replace { + for _, r := range *replace { if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { if need { // Found replacement for old; update to use new. r.New = new - f.Syntax.updateLine(r.Syntax, tokens...) + syntax.updateLine(r.Syntax, tokens...) need = false continue } @@ -1243,7 +1325,7 @@ func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { } } if need { - f.Replace = append(f.Replace, &Replace{Old: old, New: new, Syntax: f.Syntax.addLine(hint, tokens...)}) + *replace = append(*replace, &Replace{Old: old, New: new, Syntax: syntax.addLine(hint, tokens...)}) } return nil } @@ -1329,30 +1411,36 @@ func (f *File) SortBlocks() { // retract directives are not de-duplicated since comments are // meaningful, and versions may be retracted multiple times. func (f *File) removeDups() { + removeDups(f.Syntax, &f.Exclude, &f.Replace) +} + +func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace) { kill := make(map[*Line]bool) // Remove duplicate excludes. - haveExclude := make(map[module.Version]bool) - for _, x := range f.Exclude { - if haveExclude[x.Mod] { - kill[x.Syntax] = true - continue + if exclude != nil { + haveExclude := make(map[module.Version]bool) + for _, x := range *exclude { + if haveExclude[x.Mod] { + kill[x.Syntax] = true + continue + } + haveExclude[x.Mod] = true } - haveExclude[x.Mod] = true - } - var excl []*Exclude - for _, x := range f.Exclude { - if !kill[x.Syntax] { - excl = append(excl, x) + var excl []*Exclude + for _, x := range *exclude { + if !kill[x.Syntax] { + excl = append(excl, x) + } } + *exclude = excl } - f.Exclude = excl // Remove duplicate replacements. // Later replacements take priority over earlier ones. haveReplace := make(map[module.Version]bool) - for i := len(f.Replace) - 1; i >= 0; i-- { - x := f.Replace[i] + for i := len(*replace) - 1; i >= 0; i-- { + x := (*replace)[i] if haveReplace[x.Old] { kill[x.Syntax] = true continue @@ -1360,18 +1448,18 @@ func (f *File) removeDups() { haveReplace[x.Old] = true } var repl []*Replace - for _, x := range f.Replace { + for _, x := range *replace { if !kill[x.Syntax] { repl = append(repl, x) } } - f.Replace = repl + *replace = repl // Duplicate require and retract directives are not removed. // Drop killed statements from the syntax tree. var stmts []Expr - for _, stmt := range f.Syntax.Stmt { + for _, stmt := range syntax.Stmt { switch stmt := stmt.(type) { case *Line: if kill[stmt] { @@ -1391,7 +1479,7 @@ func (f *File) removeDups() { } stmts = append(stmts, stmt) } - f.Syntax.Stmt = stmts + syntax.Stmt = stmts } // lineLess returns whether li should be sorted before lj. It sorts diff --git a/tools/vendor/golang.org/x/mod/modfile/work.go b/tools/vendor/golang.org/x/mod/modfile/work.go new file mode 100644 index 00000000..0c0e5215 --- /dev/null +++ b/tools/vendor/golang.org/x/mod/modfile/work.go @@ -0,0 +1,234 @@ +// Copyright 2021 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 modfile + +import ( + "fmt" + "sort" + "strings" +) + +// A WorkFile is the parsed, interpreted form of a go.work file. +type WorkFile struct { + Go *Go + Use []*Use + Replace []*Replace + + Syntax *FileSyntax +} + +// A Use is a single directory statement. +type Use struct { + Path string // Use path of module. + ModulePath string // Module path in the comment. + Syntax *Line +} + +// ParseWork parses and returns a go.work file. +// +// file is the name of the file, used in positions and errors. +// +// data is the content of the file. +// +// fix is an optional function that canonicalizes module versions. +// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// must return the same string). +func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { + fs, err := parse(file, data) + if err != nil { + return nil, err + } + f := &WorkFile{ + Syntax: fs, + } + var errs ErrorList + + for _, x := range fs.Stmt { + switch x := x.(type) { + case *Line: + f.add(&errs, x, x.Token[0], x.Token[1:], fix) + + case *LineBlock: + if len(x.Token) > 1 { + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + } + switch x.Token[0] { + default: + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + case "use", "replace": + for _, l := range x.Line { + f.add(&errs, l, x.Token[0], l.Token, fix) + } + } + } + } + + if len(errs) > 0 { + return nil, errs + } + return f, nil +} + +// Cleanup cleans up the file f after any edit operations. +// To avoid quadratic behavior, modifications like DropRequire +// clear the entry but do not remove it from the slice. +// Cleanup cleans out all the cleared entries. +func (f *WorkFile) Cleanup() { + w := 0 + for _, r := range f.Use { + if r.Path != "" { + f.Use[w] = r + w++ + } + } + f.Use = f.Use[:w] + + w = 0 + for _, r := range f.Replace { + if r.Old.Path != "" { + f.Replace[w] = r + w++ + } + } + f.Replace = f.Replace[:w] + + f.Syntax.Cleanup() +} + +func (f *WorkFile) AddGoStmt(version string) error { + if !GoVersionRE.MatchString(version) { + return fmt.Errorf("invalid language version string %q", version) + } + if f.Go == nil { + stmt := &Line{Token: []string{"go", version}} + f.Go = &Go{ + Version: version, + Syntax: stmt, + } + // Find the first non-comment-only block that's and add + // the go statement before it. That will keep file comments at the top. + i := 0 + for i = 0; i < len(f.Syntax.Stmt); i++ { + if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok { + break + } + } + f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...) + } else { + f.Go.Version = version + f.Syntax.updateLine(f.Go.Syntax, "go", version) + } + return nil +} + +func (f *WorkFile) AddUse(diskPath, modulePath string) error { + need := true + for _, d := range f.Use { + if d.Path == diskPath { + if need { + d.ModulePath = modulePath + f.Syntax.updateLine(d.Syntax, "use", AutoQuote(diskPath)) + need = false + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + } + + if need { + f.AddNewUse(diskPath, modulePath) + } + return nil +} + +func (f *WorkFile) AddNewUse(diskPath, modulePath string) { + line := f.Syntax.addLine(nil, "use", AutoQuote(diskPath)) + f.Use = append(f.Use, &Use{Path: diskPath, ModulePath: modulePath, Syntax: line}) +} + +func (f *WorkFile) SetUse(dirs []*Use) { + need := make(map[string]string) + for _, d := range dirs { + need[d.Path] = d.ModulePath + } + + for _, d := range f.Use { + if modulePath, ok := need[d.Path]; ok { + d.ModulePath = modulePath + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + + // TODO(#45713): Add module path to comment. + + for diskPath, modulePath := range need { + f.AddNewUse(diskPath, modulePath) + } + f.SortBlocks() +} + +func (f *WorkFile) DropUse(path string) error { + for _, d := range f.Use { + if d.Path == path { + d.Syntax.markRemoved() + *d = Use{} + } + } + return nil +} + +func (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func (f *WorkFile) DropReplace(oldPath, oldVers string) error { + for _, r := range f.Replace { + if r.Old.Path == oldPath && r.Old.Version == oldVers { + r.Syntax.markRemoved() + *r = Replace{} + } + } + return nil +} + +func (f *WorkFile) SortBlocks() { + f.removeDups() // otherwise sorting is unsafe + + for _, stmt := range f.Syntax.Stmt { + block, ok := stmt.(*LineBlock) + if !ok { + continue + } + sort.SliceStable(block.Line, func(i, j int) bool { + return lineLess(block.Line[i], block.Line[j]) + }) + } +} + +// removeDups removes duplicate replace directives. +// +// Later replace directives take priority. +// +// require directives are not de-duplicated. That's left up to higher-level +// logic (MVS). +// +// retract directives are not de-duplicated since comments are +// meaningful, and versions may be retracted multiple times. +func (f *WorkFile) removeDups() { + removeDups(f.Syntax, nil, &f.Replace) +} diff --git a/tools/vendor/golang.org/x/mod/module/module.go b/tools/vendor/golang.org/x/mod/module/module.go index ba97ac35..355b5a45 100644 --- a/tools/vendor/golang.org/x/mod/module/module.go +++ b/tools/vendor/golang.org/x/mod/module/module.go @@ -286,12 +286,7 @@ func fileNameOK(r rune) bool { if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { return true } - for i := 0; i < len(allowed); i++ { - if rune(allowed[i]) == r { - return true - } - } - return false + return strings.ContainsRune(allowed, r) } // It may be OK to add more ASCII punctuation here, but only carefully. // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. @@ -803,6 +798,7 @@ func unescapeString(escaped string) (string, bool) { // GOPRIVATE environment variable, as described by 'go help module-private'. // // It ignores any empty or malformed patterns in the list. +// Trailing slashes on patterns are ignored. func MatchPrefixPatterns(globs, target string) bool { for globs != "" { // Extract next non-empty glob in comma-separated list. @@ -812,6 +808,7 @@ func MatchPrefixPatterns(globs, target string) bool { } else { glob, globs = globs, "" } + glob = strings.TrimSuffix(glob, "/") if glob == "" { continue } diff --git a/tools/vendor/golang.org/x/mod/semver/semver.go b/tools/vendor/golang.org/x/mod/semver/semver.go index 7be398f8..a30a22bf 100644 --- a/tools/vendor/golang.org/x/mod/semver/semver.go +++ b/tools/vendor/golang.org/x/mod/semver/semver.go @@ -32,7 +32,6 @@ type parsed struct { short string prerelease string build string - err string } // IsValid reports whether v is a valid semantic version string. @@ -172,12 +171,10 @@ func Sort(list []string) { func parse(v string) (p parsed, ok bool) { if v == "" || v[0] != 'v' { - p.err = "missing v prefix" return } p.major, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad major version" return } if v == "" { @@ -187,13 +184,11 @@ func parse(v string) (p parsed, ok bool) { return } if v[0] != '.' { - p.err = "bad minor prefix" ok = false return } p.minor, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad minor version" return } if v == "" { @@ -202,31 +197,26 @@ func parse(v string) (p parsed, ok bool) { return } if v[0] != '.' { - p.err = "bad patch prefix" ok = false return } p.patch, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad patch version" return } if len(v) > 0 && v[0] == '-' { p.prerelease, v, ok = parsePrerelease(v) if !ok { - p.err = "bad prerelease" return } } if len(v) > 0 && v[0] == '+' { p.build, v, ok = parseBuild(v) if !ok { - p.err = "bad build" return } } if v != "" { - p.err = "junk on end" ok = false return } diff --git a/tools/vendor/golang.org/x/tools/go/analysis/passes/composite/whitelist.go b/tools/vendor/golang.org/x/tools/go/analysis/passes/composite/whitelist.go index 1e5f5fd2..f84c1871 100644 --- a/tools/vendor/golang.org/x/tools/go/analysis/passes/composite/whitelist.go +++ b/tools/vendor/golang.org/x/tools/go/analysis/passes/composite/whitelist.go @@ -26,9 +26,10 @@ var unkeyedLiteral = map[string]bool{ "unicode.Range16": true, "unicode.Range32": true, - // These three structs are used in generated test main files, + // These four structs are used in generated test main files, // but the generator can be trusted. - "testing.InternalBenchmark": true, - "testing.InternalExample": true, - "testing.InternalTest": true, + "testing.InternalBenchmark": true, + "testing.InternalExample": true, + "testing.InternalTest": true, + "testing.InternalFuzzTarget": true, } diff --git a/tools/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go b/tools/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go index 2c878824..ffa5205d 100644 --- a/tools/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go +++ b/tools/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go @@ -7,6 +7,7 @@ package tests import ( + "fmt" "go/ast" "go/token" "go/types" @@ -16,6 +17,7 @@ import ( "unicode/utf8" "golang.org/x/tools/go/analysis" + "golang.org/x/tools/internal/analysisinternal" "golang.org/x/tools/internal/typeparams" ) @@ -34,6 +36,24 @@ var Analyzer = &analysis.Analyzer{ Run: run, } +var acceptedFuzzTypes = []types.Type{ + types.Typ[types.String], + types.Typ[types.Bool], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.NewSlice(types.Universe.Lookup("byte").Type()), +} + func run(pass *analysis.Pass) (interface{}, error) { for _, f := range pass.Files { if !strings.HasSuffix(pass.Fset.File(f.Pos()).Name(), "_test.go") { @@ -54,11 +74,221 @@ func run(pass *analysis.Pass) (interface{}, error) { case strings.HasPrefix(fn.Name.Name, "Benchmark"): checkTest(pass, fn, "Benchmark") } + // run fuzz tests diagnostics only for 1.18 i.e. when analysisinternal.DiagnoseFuzzTests is turned on. + if strings.HasPrefix(fn.Name.Name, "Fuzz") && analysisinternal.DiagnoseFuzzTests { + checkTest(pass, fn, "Fuzz") + checkFuzz(pass, fn) + } } } return nil, nil } +// Checks the contents of a fuzz function. +func checkFuzz(pass *analysis.Pass, fn *ast.FuncDecl) { + params := checkFuzzCall(pass, fn) + if params != nil { + checkAddCalls(pass, fn, params) + } +} + +// Check the arguments of f.Fuzz() calls : +// 1. f.Fuzz() should call a function and it should be of type (*testing.F).Fuzz(). +// 2. The called function in f.Fuzz(func(){}) should not return result. +// 3. First argument of func() should be of type *testing.T +// 4. Second argument onwards should be of type []byte, string, bool, byte, +// rune, float32, float64, int, int8, int16, int32, int64, uint, uint8, uint16, +// uint32, uint64 +// 5. func() must not call any *F methods, e.g. (*F).Log, (*F).Error, (*F).Skip +// The only *F methods that are allowed in the (*F).Fuzz function are (*F).Failed and (*F).Name. +// Returns the list of parameters to the fuzz function, if they are valid fuzz parameters. +func checkFuzzCall(pass *analysis.Pass, fn *ast.FuncDecl) (params *types.Tuple) { + ast.Inspect(fn, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if ok { + if !isFuzzTargetDotFuzz(pass, call) { + return true + } + + // Only one argument (func) must be passed to (*testing.F).Fuzz. + if len(call.Args) != 1 { + return true + } + expr := call.Args[0] + if pass.TypesInfo.Types[expr].Type == nil { + return true + } + t := pass.TypesInfo.Types[expr].Type.Underlying() + tSign, argOk := t.(*types.Signature) + // Argument should be a function + if !argOk { + pass.ReportRangef(expr, "argument to Fuzz must be a function") + return false + } + // ff Argument function should not return + if tSign.Results().Len() != 0 { + pass.ReportRangef(expr, "fuzz target must not return any value") + } + // ff Argument function should have 1 or more argument + if tSign.Params().Len() == 0 { + pass.ReportRangef(expr, "fuzz target must have 1 or more argument") + return false + } + ok := validateFuzzArgs(pass, tSign.Params(), expr) + if ok && params == nil { + params = tSign.Params() + } + // Inspect the function that was passed as an argument to make sure that + // there are no calls to *F methods, except for Name and Failed. + ast.Inspect(expr, func(n ast.Node) bool { + if call, ok := n.(*ast.CallExpr); ok { + if !isFuzzTargetDot(pass, call, "") { + return true + } + if !isFuzzTargetDot(pass, call, "Name") && !isFuzzTargetDot(pass, call, "Failed") { + pass.ReportRangef(call, "fuzz target must not call any *F methods") + } + } + return true + }) + // We do not need to look at any calls to f.Fuzz inside of a Fuzz call, + // since they are not allowed. + return false + } + return true + }) + return params +} + +// Check that the arguments of f.Add() calls have the same number and type of arguments as +// the signature of the function passed to (*testing.F).Fuzz +func checkAddCalls(pass *analysis.Pass, fn *ast.FuncDecl, params *types.Tuple) { + ast.Inspect(fn, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if ok { + if !isFuzzTargetDotAdd(pass, call) { + return true + } + + // The first argument to function passed to (*testing.F).Fuzz is (*testing.T). + if len(call.Args) != params.Len()-1 { + pass.ReportRangef(call, "wrong number of values in call to (*testing.F).Add: %d, fuzz target expects %d", len(call.Args), params.Len()-1) + return true + } + var mismatched []int + for i, expr := range call.Args { + if pass.TypesInfo.Types[expr].Type == nil { + return true + } + t := pass.TypesInfo.Types[expr].Type + if !types.Identical(t, params.At(i+1).Type()) { + mismatched = append(mismatched, i) + } + } + // If just one of the types is mismatched report for that + // type only. Otherwise report for the whole call to (*testing.F).Add + if len(mismatched) == 1 { + 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())) + } 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)) + } + } + return true + }) +} + +// isFuzzTargetDotFuzz reports whether call is (*testing.F).Fuzz(). +func isFuzzTargetDotFuzz(pass *analysis.Pass, call *ast.CallExpr) bool { + return isFuzzTargetDot(pass, call, "Fuzz") +} + +// isFuzzTargetDotAdd reports whether call is (*testing.F).Add(). +func isFuzzTargetDotAdd(pass *analysis.Pass, call *ast.CallExpr) bool { + return isFuzzTargetDot(pass, call, "Add") +} + +// isFuzzTargetDot reports whether call is (*testing.F).(). +func isFuzzTargetDot(pass *analysis.Pass, call *ast.CallExpr, name string) bool { + if selExpr, ok := call.Fun.(*ast.SelectorExpr); ok { + if !isTestingType(pass.TypesInfo.Types[selExpr.X].Type, "F") { + return false + } + if name == "" || selExpr.Sel.Name == name { + return true + } + } + return false +} + +// Validate the arguments of fuzz target. +func validateFuzzArgs(pass *analysis.Pass, params *types.Tuple, expr ast.Expr) bool { + fLit, isFuncLit := expr.(*ast.FuncLit) + exprRange := expr + ok := true + if !isTestingType(params.At(0).Type(), "T") { + if isFuncLit { + exprRange = fLit.Type.Params.List[0].Type + } + pass.ReportRangef(exprRange, "the first parameter of a fuzz target must be *testing.T") + ok = false + } + for i := 1; i < params.Len(); i++ { + if !isAcceptedFuzzType(params.At(i).Type()) { + if isFuncLit { + curr := 0 + for _, field := range fLit.Type.Params.List { + curr += len(field.Names) + if i < curr { + exprRange = field.Type + break + } + } + } + pass.ReportRangef(exprRange, "fuzzing arguments can only have the following types: "+formatAcceptedFuzzType()) + ok = false + } + } + return ok +} + +func isTestingType(typ types.Type, testingType string) bool { + ptr, ok := typ.(*types.Pointer) + if !ok { + return false + } + named, ok := ptr.Elem().(*types.Named) + if !ok { + return false + } + return named.Obj().Pkg().Path() == "testing" && named.Obj().Name() == testingType +} + +// Validate that fuzz target function's arguments are of accepted types. +func isAcceptedFuzzType(paramType types.Type) bool { + for _, typ := range acceptedFuzzTypes { + if types.Identical(typ, paramType) { + return true + } + } + return false +} + +func formatAcceptedFuzzType() string { + var acceptedFuzzTypesStrings []string + for _, typ := range acceptedFuzzTypes { + acceptedFuzzTypesStrings = append(acceptedFuzzTypesStrings, typ.String()) + } + acceptedFuzzTypesMsg := strings.Join(acceptedFuzzTypesStrings, ", ") + return acceptedFuzzTypesMsg +} + func isExampleSuffix(s string) bool { r, size := utf8.DecodeRuneInString(s) return size > 0 && unicode.IsLower(r) diff --git a/tools/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/tools/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 1a33cd5c..84cfb807 100644 --- a/tools/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/tools/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -237,6 +237,15 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data pkg.MarkComplete() } + // SetConstraint can't be called if the constraint type is not yet complete. + // When type params are created in the 'P' case of (*importReader).obj(), + // the associated constraint type may not be complete due to recursion. + // Therefore, we defer calling SetConstraint there, and call it here instead + // after all types are complete. + for _, d := range p.later { + typeparams.SetTypeParamConstraint(d.t, d.constraint) + } + for _, typ := range p.interfaceList { typ.Complete() } @@ -244,6 +253,11 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data return pkgs, nil } +type setConstraintArgs struct { + t *typeparams.TypeParam + constraint types.Type +} + type iimporter struct { version int ipath string @@ -260,6 +274,9 @@ type iimporter struct { fake fakeFileSet interfaceList []*types.Interface + // Arguments for calls to SetConstraint that are deferred due to recursive types + later []setConstraintArgs + indent int // for tracing support } @@ -458,7 +475,11 @@ func (r *importReader) obj(name string) { } typeparams.MarkImplicit(iface) } - typeparams.SetTypeParamConstraint(t, constraint) + // The constraint type may not be complete, if we + // are in the middle of a type recursion involving type + // constraints. So, we defer SetConstraint until we have + // completely set up all types in ImportData. + r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) case 'V': typ := r.typ() diff --git a/tools/vendor/golang.org/x/tools/go/loader/loader.go b/tools/vendor/golang.org/x/tools/go/loader/loader.go index 508a1fd0..3ba91f7c 100644 --- a/tools/vendor/golang.org/x/tools/go/loader/loader.go +++ b/tools/vendor/golang.org/x/tools/go/loader/loader.go @@ -23,6 +23,7 @@ import ( "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/internal/cgo" + "golang.org/x/tools/internal/typeparams" ) var ignoreVendor build.ImportMode @@ -1053,6 +1054,7 @@ func (imp *importer) newPackageInfo(path, dir string) *PackageInfo { errorFunc: imp.conf.TypeChecker.Error, dir: dir, } + typeparams.InitInstanceInfo(&info.Info) // Copy the types.Config so we can vary it across PackageInfos. tc := imp.conf.TypeChecker diff --git a/tools/vendor/golang.org/x/tools/go/ssa/block.go b/tools/vendor/golang.org/x/tools/go/ssa/block.go new file mode 100644 index 00000000..35f31733 --- /dev/null +++ b/tools/vendor/golang.org/x/tools/go/ssa/block.go @@ -0,0 +1,118 @@ +// Copyright 2022 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 ssa + +import "fmt" + +// This file implements the BasicBlock type. + +// addEdge adds a control-flow graph edge from from to to. +func addEdge(from, to *BasicBlock) { + from.Succs = append(from.Succs, to) + to.Preds = append(to.Preds, from) +} + +// Parent returns the function that contains block b. +func (b *BasicBlock) Parent() *Function { return b.parent } + +// String returns a human-readable label of this block. +// It is not guaranteed unique within the function. +// +func (b *BasicBlock) String() string { + return fmt.Sprintf("%d", b.Index) +} + +// emit appends an instruction to the current basic block. +// If the instruction defines a Value, it is returned. +// +func (b *BasicBlock) emit(i Instruction) Value { + i.setBlock(b) + b.Instrs = append(b.Instrs, i) + v, _ := i.(Value) + return v +} + +// predIndex returns the i such that b.Preds[i] == c or panics if +// there is none. +func (b *BasicBlock) predIndex(c *BasicBlock) int { + for i, pred := range b.Preds { + if pred == c { + return i + } + } + panic(fmt.Sprintf("no edge %s -> %s", c, b)) +} + +// hasPhi returns true if b.Instrs contains φ-nodes. +func (b *BasicBlock) hasPhi() bool { + _, ok := b.Instrs[0].(*Phi) + return ok +} + +// phis returns the prefix of b.Instrs containing all the block's φ-nodes. +func (b *BasicBlock) phis() []Instruction { + for i, instr := range b.Instrs { + if _, ok := instr.(*Phi); !ok { + return b.Instrs[:i] + } + } + return nil // unreachable in well-formed blocks +} + +// replacePred replaces all occurrences of p in b's predecessor list with q. +// Ordinarily there should be at most one. +// +func (b *BasicBlock) replacePred(p, q *BasicBlock) { + for i, pred := range b.Preds { + if pred == p { + b.Preds[i] = q + } + } +} + +// replaceSucc replaces all occurrences of p in b's successor list with q. +// Ordinarily there should be at most one. +// +func (b *BasicBlock) replaceSucc(p, q *BasicBlock) { + for i, succ := range b.Succs { + if succ == p { + b.Succs[i] = q + } + } +} + +// removePred removes all occurrences of p in b's +// predecessor list and φ-nodes. +// Ordinarily there should be at most one. +// +func (b *BasicBlock) removePred(p *BasicBlock) { + phis := b.phis() + + // We must preserve edge order for φ-nodes. + j := 0 + for i, pred := range b.Preds { + if pred != p { + b.Preds[j] = b.Preds[i] + // Strike out φ-edge too. + for _, instr := range phis { + phi := instr.(*Phi) + phi.Edges[j] = phi.Edges[i] + } + j++ + } + } + // Nil out b.Preds[j:] and φ-edges[j:] to aid GC. + for i := j; i < len(b.Preds); i++ { + b.Preds[i] = nil + for _, instr := range phis { + instr.(*Phi).Edges[i] = nil + } + } + b.Preds = b.Preds[:j] + for _, instr := range phis { + phi := instr.(*Phi) + phi.Edges = phi.Edges[:j] + } +} diff --git a/tools/vendor/golang.org/x/tools/go/ssa/builder.go b/tools/vendor/golang.org/x/tools/go/ssa/builder.go index e1540dbd..4d537414 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/builder.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/builder.go @@ -125,7 +125,7 @@ func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value { // T(e) = T(e.X) = T(e.Y) after untyped constants have been // eliminated. // TODO(adonovan): not true; MyBool==MyBool yields UntypedBool. - t := fn.Pkg.typeOf(e) + t := fn.typeOf(e) var short Value // value of the short-circuit path switch e.Op { @@ -180,7 +180,7 @@ func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value { // is token.ARROW). // func (b *builder) exprN(fn *Function, e ast.Expr) Value { - typ := fn.Pkg.typeOf(e).(*types.Tuple) + typ := fn.typeOf(e).(*types.Tuple) switch e := e.(type) { case *ast.ParenExpr: return b.exprN(fn, e.X) @@ -195,7 +195,7 @@ func (b *builder) exprN(fn *Function, e ast.Expr) Value { return fn.emit(&c) case *ast.IndexExpr: - mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) + mapt := fn.typeOf(e.X).Underlying().(*types.Map) lookup := &Lookup{ X: b.expr(fn, e.X), Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()), @@ -293,7 +293,7 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ // We must still evaluate the value, though. (If it // was side-effect free, the whole call would have // been constant-folded.) - t := deref(fn.Pkg.typeOf(args[0])).Underlying() + t := deref(fn.typeOf(args[0])).Underlying() if at, ok := t.(*types.Array); ok { b.expr(fn, args[0]) // for effects only return intConst(at.Len()) @@ -340,15 +340,17 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { if isBlankIdent(e) { return blank{} } - obj := fn.Pkg.objectOf(e) - v := fn.Prog.packageLevelValue(obj) // var (address) - if v == nil { + obj := fn.objectOf(e) + var v Value + if g := fn.Prog.packageLevelMember(obj); g != nil { + v = g.(*Global) // var (address) + } else { v = fn.lookup(obj, escaping) } return &address{addr: v, pos: e.Pos(), expr: e} case *ast.CompositeLit: - t := deref(fn.Pkg.typeOf(e)) + t := deref(fn.typeOf(e)) var v *Alloc if escaping { v = emitNew(fn, t, e.Lbrace) @@ -365,7 +367,7 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { return b.addr(fn, e.X, escaping) case *ast.SelectorExpr: - sel, ok := fn.Pkg.info.Selections[e] + sel, ok := fn.info.Selections[e] if !ok { // qualified identifier return b.addr(fn, e.Sel, escaping) @@ -385,7 +387,7 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { case *ast.IndexExpr: var x Value var et types.Type - switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { + switch t := fn.typeOf(e.X).Underlying().(type) { case *types.Array: x = b.addr(fn, e.X, escaping).address(fn) et = types.NewPointer(t.Elem()) @@ -513,7 +515,7 @@ func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb * func (b *builder) expr(fn *Function, e ast.Expr) Value { e = unparen(e) - tv := fn.Pkg.info.Types[e] + tv := fn.info.Types[e] // Is expression a constant? if tv.Value != nil { @@ -543,12 +545,13 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { case *ast.FuncLit: fn2 := &Function{ name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)), - Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature), + Signature: fn.typeOf(e.Type).Underlying().(*types.Signature), pos: e.Type.Func, parent: fn, Pkg: fn.Pkg, Prog: fn.Prog, syntax: e, + info: fn.info, } fn.AnonFuncs = append(fn.AnonFuncs, fn2) b.buildFunction(fn2) @@ -567,7 +570,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { return emitTypeAssert(fn, b.expr(fn, e.X), tv.Type, e.Lparen) case *ast.CallExpr: - if fn.Pkg.info.Types[e.Fun].IsType() { + if fn.info.Types[e.Fun].IsType() { // Explicit type conversion, e.g. string(x) or big.Int(x) x := b.expr(fn, e.Args[0]) y := emitConv(fn, x, tv.Type) @@ -587,7 +590,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { } // Call to "intrinsic" built-ins, e.g. new, make, panic. if id, ok := unparen(e.Fun).(*ast.Ident); ok { - if obj, ok := fn.Pkg.info.Uses[id].(*types.Builtin); ok { + if obj, ok := fn.info.Uses[id].(*types.Builtin); ok { if v := b.builtin(fn, obj, e.Args, tv.Type, e.Lparen); v != nil { return v } @@ -645,7 +648,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { case *ast.SliceExpr: var low, high, max Value var x Value - switch fn.Pkg.typeOf(e.X).Underlying().(type) { + switch fn.typeOf(e.X).Underlying().(type) { case *types.Array: // Potentially escaping. x = b.addr(fn, e.X, true).address(fn) @@ -674,7 +677,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { return fn.emit(v) case *ast.Ident: - obj := fn.Pkg.info.Uses[e] + obj := fn.info.Uses[e] // Universal built-in or nil? switch obj := obj.(type) { case *types.Builtin: @@ -683,20 +686,20 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { return nilConst(tv.Type) } // Package-level func or var? - if v := fn.Prog.packageLevelValue(obj); v != nil { - if _, ok := obj.(*types.Var); ok { - return emitLoad(fn, v) // var (address) + if v := fn.Prog.packageLevelMember(obj); v != nil { + if g, ok := v.(*Global); ok { + return emitLoad(fn, g) // var (address) } - return v // (func) + return v.(*Function) // (func) } // Local var. return emitLoad(fn, fn.lookup(obj, false)) // var (address) case *ast.SelectorExpr: - sel, ok := fn.Pkg.info.Selections[e] + sel, ok := fn.info.Selections[e] if !ok { // builtin unsafe.{Add,Slice} - if obj, ok := fn.Pkg.info.Uses[e.Sel].(*types.Builtin); ok { + if obj, ok := fn.info.Uses[e.Sel].(*types.Builtin); ok { return &Builtin{name: obj.Name(), sig: tv.Type.(*types.Signature)} } // qualified identifier @@ -742,7 +745,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { panic("unexpected expression-relative selector") case *ast.IndexExpr: - switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { + switch t := fn.typeOf(e.X).Underlying().(type) { case *types.Array: // Non-addressable array (in a register). v := &Index{ @@ -755,7 +758,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { case *types.Map: // Maps are not addressable. - mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) + mapt := fn.typeOf(e.X).Underlying().(*types.Map) v := &Lookup{ X: b.expr(fn, e.X), Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()), @@ -810,7 +813,7 @@ func (b *builder) stmtList(fn *Function, list []ast.Stmt) { // func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *types.Selection) Value { var v Value - if wantAddr && !sel.Indirect() && !isPointer(fn.Pkg.typeOf(e)) { + if wantAddr && !sel.Indirect() && !isPointer(fn.typeOf(e)) { v = b.addr(fn, e, escaping).address(fn) } else { v = b.expr(fn, e) @@ -833,7 +836,7 @@ func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) { // Is this a method call? if selector, ok := unparen(e.Fun).(*ast.SelectorExpr); ok { - sel, ok := fn.Pkg.info.Selections[selector] + sel, ok := fn.info.Selections[selector] if ok && sel.Kind() == types.MethodVal { obj := sel.Obj().(*types.Func) recv := recvType(obj) @@ -968,7 +971,7 @@ func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { b.setCallFunc(fn, e, c) // Then append the other actual parameters. - sig, _ := fn.Pkg.typeOf(e.Fun).Underlying().(*types.Signature) + sig, _ := fn.typeOf(e.Fun).Underlying().(*types.Signature) if sig == nil { panic(fmt.Sprintf("no signature for call of %s", e.Fun)) } @@ -1035,7 +1038,7 @@ func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) { var lval lvalue = blank{} if !isBlankIdent(lhs) { if isDef { - if obj := fn.Pkg.info.Defs[lhs.(*ast.Ident)]; obj != nil { + if obj := fn.info.Defs[lhs.(*ast.Ident)]; obj != nil { fn.addNamedLocal(obj) isZero[i] = true } @@ -1103,7 +1106,7 @@ func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 { // In that case, addr must hold a T, not a *T. // func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) { - typ := deref(fn.Pkg.typeOf(e)) + typ := deref(fn.typeOf(e)) switch t := typ.Underlying().(type) { case *types.Struct: if !isZero && len(e.Elts) != t.NumFields() { @@ -1402,7 +1405,7 @@ func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lbl var ti Value // ti, ok := typeassert,ok x for _, cond := range cc.List { next = fn.newBasicBlock("typeswitch.next") - casetype = fn.Pkg.typeOf(cond) + casetype = fn.typeOf(cond) var condv Value if casetype == tUntypedNil { condv = emitCompare(fn, token.EQL, x, nilConst(x.Type()), token.NoPos) @@ -1431,7 +1434,7 @@ func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lbl } func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) { - if obj := fn.Pkg.info.Implicits[cc]; obj != nil { + if obj := fn.info.Implicits[cc]; obj != nil { // In a switch y := x.(type), each case clause // implicitly declares a distinct object y. // In a single-type case, y has that type. @@ -1891,10 +1894,10 @@ func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, pos token.Pos) func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) { var tk, tv types.Type if s.Key != nil && !isBlankIdent(s.Key) { - tk = fn.Pkg.typeOf(s.Key) + tk = fn.typeOf(s.Key) } if s.Value != nil && !isBlankIdent(s.Value) { - tv = fn.Pkg.typeOf(s.Value) + tv = fn.typeOf(s.Value) } // If iteration variables are defined (:=), this @@ -1997,7 +2000,7 @@ start: fn.emit(&Send{ Chan: b.expr(fn, s.Chan), X: emitConv(fn, b.expr(fn, s.Value), - fn.Pkg.typeOf(s.Chan).Underlying().(*types.Chan).Elem()), + fn.typeOf(s.Chan).Underlying().(*types.Chan).Elem()), pos: s.Arrow, }) @@ -2224,7 +2227,7 @@ func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) { if isBlankIdent(id) { return // discard } - fn := pkg.values[pkg.info.Defs[id]].(*Function) + fn := pkg.objects[pkg.info.Defs[id]].(*Function) if decl.Recv == nil && id.Name == "init" { var v Call v.Call.Value = fn @@ -2324,7 +2327,7 @@ func (p *Package) build() { // 1:1 initialization: var x, y = a(), b() var lval lvalue if v := varinit.Lhs[0]; v.Name() != "_" { - lval = &address{addr: p.values[v].(*Global), pos: v.Pos()} + lval = &address{addr: p.objects[v].(*Global), pos: v.Pos()} } else { lval = blank{} } @@ -2336,7 +2339,7 @@ func (p *Package) build() { if v.Name() == "_" { continue } - emitStore(init, p.values[v].(*Global), emitExtract(init, tuple, i), v.Pos()) + emitStore(init, p.objects[v].(*Global), emitExtract(init, tuple, i), v.Pos()) } } } @@ -2366,23 +2369,3 @@ func (p *Package) build() { sanityCheckPackage(p) } } - -// Like ObjectOf, but panics instead of returning nil. -// Only valid during p's create and build phases. -func (p *Package) objectOf(id *ast.Ident) types.Object { - if o := p.info.ObjectOf(id); o != nil { - return o - } - panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s", - id.Name, p.Prog.Fset.Position(id.Pos()))) -} - -// Like TypeOf, but panics instead of returning nil. -// Only valid during p's create and build phases. -func (p *Package) typeOf(e ast.Expr) types.Type { - if T := p.info.TypeOf(e); T != nil { - return T - } - panic(fmt.Sprintf("no type for %T @ %s", - e, p.Prog.Fset.Position(e.Pos()))) -} diff --git a/tools/vendor/golang.org/x/tools/go/ssa/create.go b/tools/vendor/golang.org/x/tools/go/ssa/create.go index 85163a0c..69cd9371 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/create.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/create.go @@ -34,7 +34,6 @@ func NewProgram(fset *token.FileSet, mode BuilderMode) *Program { h := typeutil.MakeHasher() // protected by methodsMu, in effect prog.methodSets.SetHasher(h) - prog.canon.SetHasher(h) return prog } @@ -66,7 +65,7 @@ func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) { Value: NewConst(obj.Val(), obj.Type()), pkg: pkg, } - pkg.values[obj] = c.Value + pkg.objects[obj] = c pkg.Members[name] = c case *types.Var: @@ -77,7 +76,7 @@ func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) { typ: types.NewPointer(obj.Type()), // address pos: obj.Pos(), } - pkg.values[obj] = g + pkg.objects[obj] = g pkg.Members[name] = g case *types.Func: @@ -94,12 +93,13 @@ func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) { pos: obj.Pos(), Pkg: pkg, Prog: pkg.Prog, + info: pkg.info, } if syntax == nil { fn.Synthetic = "loaded from gc object file" } - pkg.values[obj] = fn + pkg.objects[obj] = fn if sig.Recv() == nil { pkg.Members[name] = fn // package-level function } @@ -166,7 +166,7 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info * p := &Package{ Prog: prog, Members: make(map[string]Member), - values: make(map[types.Object]Value), + objects: make(map[types.Object]Member), Pkg: pkg, info: info, // transient (CREATE and BUILD phases) files: files, // transient (CREATE and BUILD phases) @@ -179,6 +179,7 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info * Synthetic: "package initializer", Pkg: p, Prog: prog, + info: p.info, } p.Members[p.init.name] = p.init diff --git a/tools/vendor/golang.org/x/tools/go/ssa/emit.go b/tools/vendor/golang.org/x/tools/go/ssa/emit.go index 7c8cfdc6..576e0245 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/emit.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/emit.go @@ -50,7 +50,7 @@ func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) { if isBlankIdent(id) { return } - obj = f.Pkg.objectOf(id) + obj = f.objectOf(id) switch obj.(type) { case *types.Nil, *types.Const, *types.Builtin: return @@ -74,9 +74,16 @@ func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token. case token.SHL, token.SHR: x = emitConv(f, x, t) // y may be signed or an 'untyped' constant. - // TODO(adonovan): whence signed values? - if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUnsigned == 0 { - y = emitConv(f, y, types.Typ[types.Uint64]) + + // There is a runtime panic if y is signed and <0. Instead of inserting a check for y<0 + // and converting to an unsigned value (like the compiler) leave y as is. + + if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { + // Untyped conversion: + // Spec https://go.dev/ref/spec#Operators: + // The right operand in a shift expression must have integer type or be an untyped constant + // representable by a value of type uint. + y = emitConv(f, y, types.Typ[types.Uint]) } case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: diff --git a/tools/vendor/golang.org/x/tools/go/ssa/func.go b/tools/vendor/golang.org/x/tools/go/ssa/func.go index 0b99bc9b..8fc089e5 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/func.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/func.go @@ -4,7 +4,7 @@ package ssa -// This file implements the Function and BasicBlock types. +// This file implements the Function type. import ( "bytes" @@ -17,113 +17,23 @@ import ( "strings" ) -// addEdge adds a control-flow graph edge from from to to. -func addEdge(from, to *BasicBlock) { - from.Succs = append(from.Succs, to) - to.Preds = append(to.Preds, from) -} - -// Parent returns the function that contains block b. -func (b *BasicBlock) Parent() *Function { return b.parent } - -// String returns a human-readable label of this block. -// It is not guaranteed unique within the function. -// -func (b *BasicBlock) String() string { - return fmt.Sprintf("%d", b.Index) -} - -// emit appends an instruction to the current basic block. -// If the instruction defines a Value, it is returned. -// -func (b *BasicBlock) emit(i Instruction) Value { - i.setBlock(b) - b.Instrs = append(b.Instrs, i) - v, _ := i.(Value) - return v -} - -// predIndex returns the i such that b.Preds[i] == c or panics if -// there is none. -func (b *BasicBlock) predIndex(c *BasicBlock) int { - for i, pred := range b.Preds { - if pred == c { - return i - } - } - panic(fmt.Sprintf("no edge %s -> %s", c, b)) -} - -// hasPhi returns true if b.Instrs contains φ-nodes. -func (b *BasicBlock) hasPhi() bool { - _, ok := b.Instrs[0].(*Phi) - return ok -} - -// phis returns the prefix of b.Instrs containing all the block's φ-nodes. -func (b *BasicBlock) phis() []Instruction { - for i, instr := range b.Instrs { - if _, ok := instr.(*Phi); !ok { - return b.Instrs[:i] - } - } - return nil // unreachable in well-formed blocks -} - -// replacePred replaces all occurrences of p in b's predecessor list with q. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) replacePred(p, q *BasicBlock) { - for i, pred := range b.Preds { - if pred == p { - b.Preds[i] = q - } - } -} - -// replaceSucc replaces all occurrences of p in b's successor list with q. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) replaceSucc(p, q *BasicBlock) { - for i, succ := range b.Succs { - if succ == p { - b.Succs[i] = q - } +// Like ObjectOf, but panics instead of returning nil. +// Only valid during f's create and build phases. +func (f *Function) objectOf(id *ast.Ident) types.Object { + if o := f.info.ObjectOf(id); o != nil { + return o } + panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s", + id.Name, f.Prog.Fset.Position(id.Pos()))) } -// removePred removes all occurrences of p in b's -// predecessor list and φ-nodes. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) removePred(p *BasicBlock) { - phis := b.phis() - - // We must preserve edge order for φ-nodes. - j := 0 - for i, pred := range b.Preds { - if pred != p { - b.Preds[j] = b.Preds[i] - // Strike out φ-edge too. - for _, instr := range phis { - phi := instr.(*Phi) - phi.Edges[j] = phi.Edges[i] - } - j++ - } - } - // Nil out b.Preds[j:] and φ-edges[j:] to aid GC. - for i := j; i < len(b.Preds); i++ { - b.Preds[i] = nil - for _, instr := range phis { - instr.(*Phi).Edges[i] = nil - } - } - b.Preds = b.Preds[:j] - for _, instr := range phis { - phi := instr.(*Phi) - phi.Edges = phi.Edges[:j] +// Like TypeOf, but panics instead of returning nil. +// Only valid during f's create and build phases. +func (f *Function) typeOf(e ast.Expr) types.Type { + if T := f.info.TypeOf(e); T != nil { + return T } + panic(fmt.Sprintf("no type for %T @ %s", e, f.Prog.Fset.Position(e.Pos()))) } // Destinations associated with unlabelled for/switch/select stmts. @@ -214,7 +124,7 @@ func (f *Function) startBody() { // syntax. In addition it populates the f.objects mapping. // // Preconditions: -// f.startBody() was called. +// f.startBody() was called. f.info != nil. // Postcondition: // len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0) // @@ -223,7 +133,7 @@ func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.Func if recv != nil { for _, field := range recv.List { for _, n := range field.Names { - f.addSpilledParam(f.Pkg.info.Defs[n]) + f.addSpilledParam(f.info.Defs[n]) } // Anonymous receiver? No need to spill. if field.Names == nil { @@ -237,7 +147,7 @@ func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.Func n := len(f.Params) // 1 if has recv, 0 otherwise for _, field := range functype.Params.List { for _, n := range field.Names { - f.addSpilledParam(f.Pkg.info.Defs[n]) + f.addSpilledParam(f.info.Defs[n]) } // Anonymous parameter? No need to spill. if field.Names == nil { @@ -335,7 +245,9 @@ func (f *Function) finishBody() { lift(f) } + // clear remaining stateful variables f.namedResults = nil // (used by lifting) + f.info = nil numberRegisters(f) @@ -396,7 +308,7 @@ func (f *Function) addNamedLocal(obj types.Object) *Alloc { } func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc { - return f.addNamedLocal(f.Pkg.info.Defs[id]) + return f.addNamedLocal(f.info.Defs[id]) } // addLocal creates an anonymous local variable of type typ, adds it @@ -502,7 +414,7 @@ func (f *Function) RelString(from *types.Package) string { // Package-level function? // Prefix with package name for cross-package references only. - if p := f.pkg(); p != nil && p != from { + if p := f.relPkg(); p != nil && p != from { return fmt.Sprintf("%s.%s", p.Path(), f.name) } @@ -530,9 +442,26 @@ func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *ty types.WriteSignature(buf, sig, types.RelativeTo(from)) } -func (f *Function) pkg() *types.Package { - if f.Pkg != nil { - return f.Pkg.Pkg +// declaredPackage returns the package fn is declared in or nil if the +// function is not declared in a package. +func (fn *Function) declaredPackage() *Package { + switch { + case fn.Pkg != nil: + return fn.Pkg // non-generic function + // generics: + // case fn.Origin != nil: + // return fn.Origin.pkg // instance of a named generic function + case fn.parent != nil: + return fn.parent.declaredPackage() // instance of an anonymous [generic] function + default: + return nil // function is not declared in a package, e.g. a wrapper. + } +} + +// relPkg returns types.Package fn is printed in relationship to. +func (fn *Function) relPkg() *types.Package { + if p := fn.declaredPackage(); p != nil { + return p.Pkg } return nil } @@ -567,7 +496,7 @@ func WriteFunction(buf *bytes.Buffer, f *Function) { fmt.Fprintf(buf, "# Recover: %s\n", f.Recover) } - from := f.pkg() + from := f.relPkg() if f.FreeVars != nil { buf.WriteString("# Free variables:\n") diff --git a/tools/vendor/golang.org/x/tools/go/ssa/methods.go b/tools/vendor/golang.org/x/tools/go/ssa/methods.go index 9cf38391..22e1f3f0 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/methods.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/methods.go @@ -118,7 +118,7 @@ func (prog *Program) RuntimeTypes() []types.Type { // Panic ensues if there is none. // func (prog *Program) declaredFunc(obj *types.Func) *Function { - if v := prog.packageLevelValue(obj); v != nil { + if v := prog.packageLevelMember(obj); v != nil { return v.(*Function) } panic("no concrete method: " + obj.String()) diff --git a/tools/vendor/golang.org/x/tools/go/ssa/parameterized.go b/tools/vendor/golang.org/x/tools/go/ssa/parameterized.go new file mode 100644 index 00000000..956718cd --- /dev/null +++ b/tools/vendor/golang.org/x/tools/go/ssa/parameterized.go @@ -0,0 +1,113 @@ +// Copyright 2022 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 ssa + +import ( + "go/types" + + "golang.org/x/tools/internal/typeparams" +) + +// tpWalker walks over types looking for parameterized types. +// +// NOTE: Adapted from go/types/infer.go. If that is exported in a future release remove this copy. +type tpWalker struct { + seen map[types.Type]bool +} + +// isParameterized returns true when typ contains any type parameters. +func (w *tpWalker) isParameterized(typ types.Type) (res bool) { + // NOTE: Adapted from go/types/infer.go. Try to keep in sync. + + // detect cycles + if x, ok := w.seen[typ]; ok { + return x + } + w.seen[typ] = false + defer func() { + w.seen[typ] = res + }() + + switch t := typ.(type) { + case nil, *types.Basic: // TODO(gri) should nil be handled here? + break + + case *types.Array: + return w.isParameterized(t.Elem()) + + case *types.Slice: + return w.isParameterized(t.Elem()) + + case *types.Struct: + for i, n := 0, t.NumFields(); i < n; i++ { + if w.isParameterized(t.Field(i).Type()) { + return true + } + } + + case *types.Pointer: + return w.isParameterized(t.Elem()) + + case *types.Tuple: + n := t.Len() + for i := 0; i < n; i++ { + if w.isParameterized(t.At(i).Type()) { + return true + } + } + + case *types.Signature: + // t.tparams may not be nil if we are looking at a signature + // of a generic function type (or an interface method) that is + // part of the type we're testing. We don't care about these type + // parameters. + // Similarly, the receiver of a method may declare (rather then + // use) type parameters, we don't care about those either. + // Thus, we only need to look at the input and result parameters. + return w.isParameterized(t.Params()) || w.isParameterized(t.Results()) + + case *types.Interface: + for i, n := 0, t.NumMethods(); i < n; i++ { + if w.isParameterized(t.Method(i).Type()) { + return true + } + } + terms, err := typeparams.InterfaceTermSet(t) + if err != nil { + panic(err) + } + for _, term := range terms { + if w.isParameterized(term.Type()) { + return true + } + } + + case *types.Map: + return w.isParameterized(t.Key()) || w.isParameterized(t.Elem()) + + case *types.Chan: + return w.isParameterized(t.Elem()) + + case *types.Named: + args := typeparams.NamedTypeArgs(t) + // TODO(taking): this does not match go/types/infer.go. Check with rfindley. + if params := typeparams.ForNamed(t); params.Len() > args.Len() { + return true + } + for i, n := 0, args.Len(); i < n; i++ { + if w.isParameterized(args.At(i)) { + return true + } + } + + case *typeparams.TypeParam: + return true + + default: + panic(t) // unreachable + } + + return false +} diff --git a/tools/vendor/golang.org/x/tools/go/ssa/print.go b/tools/vendor/golang.org/x/tools/go/ssa/print.go index 5995f83a..d0f3bbf7 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/print.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/print.go @@ -28,7 +28,7 @@ import ( func relName(v Value, i Instruction) string { var from *types.Package if i != nil { - from = i.Parent().pkg() + from = i.Parent().relPkg() } switch v := v.(type) { case Member: // *Function or *Global @@ -66,12 +66,12 @@ func relString(m Member, from *types.Package) string { // It never appears in disassembly, which uses Value.Name(). func (v *Parameter) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from)) } func (v *FreeVar) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from)) } @@ -86,7 +86,7 @@ func (v *Alloc) String() string { if v.Heap { op = "new" } - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment) } @@ -160,7 +160,7 @@ func (v *UnOp) String() string { } func printConv(prefix string, v, x Value) string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("%s %s <- %s (%s)", prefix, relType(v.Type(), from), @@ -191,7 +191,7 @@ func (v *MakeClosure) String() string { } func (v *MakeSlice) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s %s", relType(v.Type(), from), relName(v.Len, v), @@ -223,12 +223,12 @@ func (v *MakeMap) String() string { if v.Reserve != nil { res = relName(v.Reserve, v) } - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s", relType(v.Type(), from), res) } func (v *MakeChan) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v)) } @@ -273,7 +273,7 @@ func (v *Next) String() string { } func (v *TypeAssert) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from)) } diff --git a/tools/vendor/golang.org/x/tools/go/ssa/sanity.go b/tools/vendor/golang.org/x/tools/go/ssa/sanity.go index 1d4e20f6..6e65d760 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/sanity.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/sanity.go @@ -409,8 +409,8 @@ func (s *sanity) checkFunction(fn *Function) bool { s.errorf("nil Prog") } - _ = fn.String() // must not crash - _ = fn.RelString(fn.pkg()) // must not crash + _ = fn.String() // must not crash + _ = fn.RelString(fn.relPkg()) // must not crash // All functions have a package, except delegates (which are // shared across packages, or duplicated as weak symbols in a diff --git a/tools/vendor/golang.org/x/tools/go/ssa/source.go b/tools/vendor/golang.org/x/tools/go/ssa/source.go index 8d9cca17..7e2a369d 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/source.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/source.go @@ -123,7 +123,7 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function { // Don't call Program.Method: avoid creating wrappers. obj := mset.At(i).Obj().(*types.Func) if obj.Pos() == pos { - return pkg.values[obj].(*Function) + return pkg.objects[obj].(*Function) } } } @@ -180,14 +180,14 @@ func (prog *Program) Package(obj *types.Package) *Package { return prog.packages[obj] } -// packageLevelValue returns the package-level value corresponding to +// packageLevelMember returns the package-level member corresponding to // the specified named object, which may be a package-level const -// (*Const), var (*Global) or func (*Function) of some package in +// (*NamedConst), var (*Global) or func (*Function) of some package in // prog. It returns nil if the object is not found. // -func (prog *Program) packageLevelValue(obj types.Object) Value { +func (prog *Program) packageLevelMember(obj types.Object) Member { if pkg, ok := prog.packages[obj.Pkg()]; ok { - return pkg.values[obj] + return pkg.objects[obj] } return nil } @@ -199,7 +199,7 @@ func (prog *Program) packageLevelValue(obj types.Object) Value { // result's Signature, both in the params/results and in the receiver. // func (prog *Program) FuncValue(obj *types.Func) *Function { - fn, _ := prog.packageLevelValue(obj).(*Function) + fn, _ := prog.packageLevelMember(obj).(*Function) return fn } @@ -215,8 +215,8 @@ func (prog *Program) ConstValue(obj *types.Const) *Const { return NewConst(obj.Val(), obj.Type()) } // Package-level named constant? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Const) + if v := prog.packageLevelMember(obj); v != nil { + return v.(*NamedConst).Value } return NewConst(obj.Val(), obj.Type()) } @@ -285,7 +285,7 @@ func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (val } // Defining ident of package-level var? - if v := prog.packageLevelValue(obj); v != nil { + if v := prog.packageLevelMember(obj); v != nil { return v.(*Global), true } diff --git a/tools/vendor/golang.org/x/tools/go/ssa/ssa.go b/tools/vendor/golang.org/x/tools/go/ssa/ssa.go index 8358681c..ea5b68e2 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/ssa.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/ssa.go @@ -26,10 +26,11 @@ type Program struct { mode BuilderMode // set of mode bits for SSA construction MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets + canon canonizer // type canonicalization map + methodsMu sync.Mutex // guards the following maps: methodSets typeutil.Map // maps type to its concrete methodSet runtimeTypes typeutil.Map // types for which rtypes are needed - canon typeutil.Map // type canonicalization map bounds map[*types.Func]*Function // bounds for curried x.Method closures thunks map[selectionKey]*Function // thunks for T.Method expressions } @@ -44,12 +45,12 @@ type Program struct { // and unspecified other things too. // type Package struct { - Prog *Program // the owning program - Pkg *types.Package // the corresponding go/types.Package - Members map[string]Member // all package members keyed by name (incl. init and init#%d) - values map[types.Object]Value // package members (incl. types and methods), keyed by object - init *Function // Func("init"); the package's init function - debug bool // include full debug info in this package + Prog *Program // the owning program + Pkg *types.Package // the corresponding go/types.Package + Members map[string]Member // all package members keyed by name (incl. init and init#%d) + objects map[types.Object]Member // mapping of package objects to members (incl. methods). Contains *NamedConst, *Global, *Function. + init *Function // Func("init"); the package's init function + debug bool // include full debug info in this package // The following fields are set transiently, then cleared // after building. @@ -320,6 +321,7 @@ type Function struct { namedResults []*Alloc // tuple of named results targets *targets // linked stack of branch targets lblocks map[*ast.Object]*lblock // labelled blocks + info *types.Info // *types.Info to build from. nil for wrappers. } // BasicBlock represents an SSA basic block. diff --git a/tools/vendor/golang.org/x/tools/go/ssa/ssautil/load.go b/tools/vendor/golang.org/x/tools/go/ssa/ssautil/load.go index 18e88e6a..88d7c8f4 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/ssautil/load.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/ssautil/load.go @@ -14,6 +14,7 @@ import ( "golang.org/x/tools/go/loader" "golang.org/x/tools/go/packages" "golang.org/x/tools/go/ssa" + "golang.org/x/tools/internal/typeparams" ) // Packages creates an SSA program for a set of packages. @@ -147,6 +148,7 @@ func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, fil Scopes: make(map[ast.Node]*types.Scope), Selections: make(map[*ast.SelectorExpr]*types.Selection), } + typeparams.InitInstanceInfo(info) if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { return nil, nil, err } diff --git a/tools/vendor/golang.org/x/tools/go/ssa/subst.go b/tools/vendor/golang.org/x/tools/go/ssa/subst.go new file mode 100644 index 00000000..0e9263fd --- /dev/null +++ b/tools/vendor/golang.org/x/tools/go/ssa/subst.go @@ -0,0 +1,432 @@ +// Copyright 2022 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 ssa + +import ( + "fmt" + "go/types" + + "golang.org/x/tools/internal/typeparams" +) + +// Type substituter for a fixed set of replacement types. +// +// A nil *subster is an valid, empty substitution map. It always acts as +// the identity function. This allows for treating parameterized and +// non-parameterized functions identically while compiling to ssa. +// +// Not concurrency-safe. +type subster struct { + replacements map[*typeparams.TypeParam]types.Type // values should contain no type params + cache map[types.Type]types.Type // cache of subst results + ctxt *typeparams.Context + debug bool // perform extra debugging checks + // TODO(taking): consider adding Pos +} + +// Returns a subster that replaces tparams[i] with targs[i]. Uses ctxt as a cache. +// targs should not contain any types in tparams. +func makeSubster(ctxt *typeparams.Context, tparams []*typeparams.TypeParam, targs []types.Type, debug bool) *subster { + assert(len(tparams) == len(targs), "makeSubster argument count must match") + + subst := &subster{ + replacements: make(map[*typeparams.TypeParam]types.Type, len(tparams)), + cache: make(map[types.Type]types.Type), + ctxt: ctxt, + debug: debug, + } + for i, tpar := range tparams { + subst.replacements[tpar] = targs[i] + } + if subst.debug { + if err := subst.wellFormed(); err != nil { + panic(err) + } + } + return subst +} + +// wellFormed returns an error if subst was not properly initialized. +func (subst *subster) wellFormed() error { + if subst == nil || len(subst.replacements) == 0 { + return nil + } + // Check that all of the type params do not appear in the arguments. + s := make(map[types.Type]bool, len(subst.replacements)) + for tparam := range subst.replacements { + s[tparam] = true + } + for _, r := range subst.replacements { + if reaches(r, s) { + return fmt.Errorf("\n‰r %s s %v replacements %v\n", r, s, subst.replacements) + } + } + return nil +} + +// typ returns the type of t with the type parameter tparams[i] substituted +// for the type targs[i] where subst was created using tparams and targs. +func (subst *subster) typ(t types.Type) (res types.Type) { + if subst == nil { + return t // A nil subst is type preserving. + } + if r, ok := subst.cache[t]; ok { + return r + } + defer func() { + subst.cache[t] = res + }() + + // fall through if result r will be identical to t, types.Identical(r, t). + switch t := t.(type) { + case *typeparams.TypeParam: + r := subst.replacements[t] + assert(r != nil, "type param without replacement encountered") + return r + + case *types.Basic: + return t + + case *types.Array: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewArray(r, t.Len()) + } + return t + + case *types.Slice: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewSlice(r) + } + return t + + case *types.Pointer: + if r := subst.typ(t.Elem()); r != t.Elem() { + return types.NewPointer(r) + } + return t + + case *types.Tuple: + return subst.tuple(t) + + case *types.Struct: + return subst.struct_(t) + + case *types.Map: + key := subst.typ(t.Key()) + elem := subst.typ(t.Elem()) + if key != t.Key() || elem != t.Elem() { + return types.NewMap(key, elem) + } + return t + + case *types.Chan: + if elem := subst.typ(t.Elem()); elem != t.Elem() { + return types.NewChan(t.Dir(), elem) + } + return t + + case *types.Signature: + return subst.signature(t) + + case *typeparams.Union: + return subst.union(t) + + case *types.Interface: + return subst.interface_(t) + + case *types.Named: + return subst.named(t) + + default: + panic("unreachable") + } +} + +func (subst *subster) tuple(t *types.Tuple) *types.Tuple { + if t != nil { + if vars := subst.varlist(t); vars != nil { + return types.NewTuple(vars...) + } + } + return t +} + +type varlist interface { + At(i int) *types.Var + Len() int +} + +// fieldlist is an adapter for structs for the varlist interface. +type fieldlist struct { + str *types.Struct +} + +func (fl fieldlist) At(i int) *types.Var { return fl.str.Field(i) } +func (fl fieldlist) Len() int { return fl.str.NumFields() } + +func (subst *subster) struct_(t *types.Struct) *types.Struct { + if t != nil { + if fields := subst.varlist(fieldlist{t}); fields != nil { + tags := make([]string, t.NumFields()) + for i, n := 0, t.NumFields(); i < n; i++ { + tags[i] = t.Tag(i) + } + return types.NewStruct(fields, tags) + } + } + return t +} + +// varlist reutrns subst(in[i]) or return nils if subst(v[i]) == v[i] for all i. +func (subst *subster) varlist(in varlist) []*types.Var { + var out []*types.Var // nil => no updates + for i, n := 0, in.Len(); i < n; i++ { + v := in.At(i) + w := subst.var_(v) + if v != w && out == nil { + out = make([]*types.Var, n) + for j := 0; j < i; j++ { + out[j] = in.At(j) + } + } + if out != nil { + out[i] = w + } + } + return out +} + +func (subst *subster) var_(v *types.Var) *types.Var { + if v != nil { + if typ := subst.typ(v.Type()); typ != v.Type() { + if v.IsField() { + return types.NewField(v.Pos(), v.Pkg(), v.Name(), typ, v.Embedded()) + } + return types.NewVar(v.Pos(), v.Pkg(), v.Name(), typ) + } + } + return v +} + +func (subst *subster) union(u *typeparams.Union) *typeparams.Union { + var out []*typeparams.Term // nil => no updates + + for i, n := 0, u.Len(); i < n; i++ { + t := u.Term(i) + r := subst.typ(t.Type()) + if r != t.Type() && out == nil { + out = make([]*typeparams.Term, n) + for j := 0; j < i; j++ { + out[j] = u.Term(j) + } + } + if out != nil { + out[i] = typeparams.NewTerm(t.Tilde(), r) + } + } + + if out != nil { + return typeparams.NewUnion(out) + } + return u +} + +func (subst *subster) interface_(iface *types.Interface) *types.Interface { + if iface == nil { + return nil + } + + // methods for the interface. Initially nil if there is no known change needed. + // Signatures for the method where recv is nil. NewInterfaceType fills in the recievers. + var methods []*types.Func + initMethods := func(n int) { // copy first n explicit methods + methods = make([]*types.Func, iface.NumExplicitMethods()) + for i := 0; i < n; i++ { + f := iface.ExplicitMethod(i) + norecv := changeRecv(f.Type().(*types.Signature), nil) + methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), norecv) + } + } + for i := 0; i < iface.NumExplicitMethods(); i++ { + f := iface.ExplicitMethod(i) + // On interfaces, we need to cycle break on anonymous interface types + // being in a cycle with their signatures being in cycles with their recievers + // that do not go through a Named. + norecv := changeRecv(f.Type().(*types.Signature), nil) + sig := subst.typ(norecv) + if sig != norecv && methods == nil { + initMethods(i) + } + if methods != nil { + methods[i] = types.NewFunc(f.Pos(), f.Pkg(), f.Name(), sig.(*types.Signature)) + } + } + + var embeds []types.Type + initEmbeds := func(n int) { // copy first n embedded types + embeds = make([]types.Type, iface.NumEmbeddeds()) + for i := 0; i < n; i++ { + embeds[i] = iface.EmbeddedType(i) + } + } + for i := 0; i < iface.NumEmbeddeds(); i++ { + e := iface.EmbeddedType(i) + r := subst.typ(e) + if e != r && embeds == nil { + initEmbeds(i) + } + if embeds != nil { + embeds[i] = r + } + } + + if methods == nil && embeds == nil { + return iface + } + if methods == nil { + initMethods(iface.NumExplicitMethods()) + } + if embeds == nil { + initEmbeds(iface.NumEmbeddeds()) + } + return types.NewInterfaceType(methods, embeds).Complete() +} + +func (subst *subster) named(t *types.Named) types.Type { + // A name type may be: + // (1) ordinary (no type parameters, no type arguments), + // (2) generic (type parameters but no type arguments), or + // (3) instantiated (type parameters and type arguments). + tparams := typeparams.ForNamed(t) + if tparams.Len() == 0 { + // case (1) ordinary + + // Note: If Go allows for local type declarations in generic + // functions we may need to descend into underlying as well. + return t + } + targs := typeparams.NamedTypeArgs(t) + + // insts are arguments to instantiate using. + insts := make([]types.Type, tparams.Len()) + + // case (2) generic ==> targs.Len() == 0 + // Instantiating a generic with no type arguments should be unreachable. + // Please report a bug if you encounter this. + assert(targs.Len() != 0, "substition into a generic Named type is currently unsupported") + + // case (3) instantiated. + // Substitute into the type arguments and instantiate the replacements/ + // Example: + // type N[A any] func() A + // func Foo[T](g N[T]) {} + // To instantiate Foo[string], one goes through {T->string}. To get the type of g + // one subsitutes T with string in {N with TypeArgs == {T} and TypeParams == {A} } + // to get {N with TypeArgs == {string} and TypeParams == {A} }. + assert(targs.Len() == tparams.Len(), "TypeArgs().Len() must match TypeParams().Len() if present") + for i, n := 0, targs.Len(); i < n; i++ { + inst := subst.typ(targs.At(i)) // TODO(generic): Check with rfindley for mutual recursion + insts[i] = inst + } + r, err := typeparams.Instantiate(subst.ctxt, typeparams.NamedTypeOrigin(t), insts, false) + assert(err == nil, "failed to Instantiate Named type") + return r +} + +func (subst *subster) signature(t *types.Signature) types.Type { + tparams := typeparams.ForSignature(t) + + // We are choosing not to support tparams.Len() > 0 until a need has been observed in practice. + // + // There are some known usages for types.Types coming from types.{Eval,CheckExpr}. + // To support tparams.Len() > 0, we just need to do the following [psuedocode]: + // targs := {subst.replacements[tparams[i]]]}; Instantiate(ctxt, t, targs, false) + + assert(tparams.Len() == 0, "Substituting types.Signatures with generic functions are currently unsupported.") + + // Either: + // (1)non-generic function. + // no type params to substitute + // (2)generic method and recv needs to be substituted. + + // Recievers can be either: + // named + // pointer to named + // interface + // nil + // interface is the problematic case. We need to cycle break there! + recv := subst.var_(t.Recv()) + params := subst.tuple(t.Params()) + results := subst.tuple(t.Results()) + if recv != t.Recv() || params != t.Params() || results != t.Results() { + return types.NewSignature(recv, params, results, t.Variadic()) + } + return t +} + +// reaches returns true if a type t reaches any type t' s.t. c[t'] == true. +// Updates c to cache results. +func reaches(t types.Type, c map[types.Type]bool) (res bool) { + if c, ok := c[t]; ok { + return c + } + c[t] = false // prevent cycles + defer func() { + c[t] = res + }() + + switch t := t.(type) { + case *typeparams.TypeParam, *types.Basic: + // no-op => c == false + case *types.Array: + return reaches(t.Elem(), c) + case *types.Slice: + return reaches(t.Elem(), c) + case *types.Pointer: + return reaches(t.Elem(), c) + case *types.Tuple: + for i := 0; i < t.Len(); i++ { + if reaches(t.At(i).Type(), c) { + return true + } + } + case *types.Struct: + for i := 0; i < t.NumFields(); i++ { + if reaches(t.Field(i).Type(), c) { + return true + } + } + case *types.Map: + return reaches(t.Key(), c) || reaches(t.Elem(), c) + case *types.Chan: + return reaches(t.Elem(), c) + case *types.Signature: + if t.Recv() != nil && reaches(t.Recv().Type(), c) { + return true + } + return reaches(t.Params(), c) || reaches(t.Results(), c) + case *typeparams.Union: + for i := 0; i < t.Len(); i++ { + if reaches(t.Term(i).Type(), c) { + return true + } + } + case *types.Interface: + for i := 0; i < t.NumEmbeddeds(); i++ { + if reaches(t.Embedded(i), c) { + return true + } + } + for i := 0; i < t.NumExplicitMethods(); i++ { + if reaches(t.ExplicitMethod(i).Type(), c) { + return true + } + } + case *types.Named: + return reaches(t.Underlying(), c) + default: + panic("unreachable") + } + return false +} diff --git a/tools/vendor/golang.org/x/tools/go/ssa/util.go b/tools/vendor/golang.org/x/tools/go/ssa/util.go index a09949a3..01021936 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/util.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/util.go @@ -13,10 +13,22 @@ import ( "go/types" "io" "os" + "sync" "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/go/types/typeutil" ) +//// Sanity checking utilities + +// assert panics with the mesage msg if p is false. +// Avoid combining with expensive string formatting. +func assert(p bool, msg string) { + if !p { + panic(msg) + } +} + //// AST utilities func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } @@ -87,3 +99,36 @@ func makeLen(T types.Type) *Builtin { sig: types.NewSignature(nil, lenParams, lenResults, false), } } + +// Mapping of a type T to a canonical instance C s.t. types.Indentical(T, C). +// Thread-safe. +type canonizer struct { + mu sync.Mutex + canon typeutil.Map // map from type to a canonical instance +} + +// Tuple returns a canonical representative of a Tuple of types. +// Representative of the empty Tuple is nil. +func (c *canonizer) Tuple(ts []types.Type) *types.Tuple { + if len(ts) == 0 { + return nil + } + vars := make([]*types.Var, len(ts)) + for i, t := range ts { + vars[i] = anonVar(t) + } + tuple := types.NewTuple(vars...) + return c.Type(tuple).(*types.Tuple) +} + +// Type returns a canonical representative of type T. +func (c *canonizer) Type(T types.Type) types.Type { + c.mu.Lock() + defer c.mu.Unlock() + + if r := c.canon.At(T); r != nil { + return r.(types.Type) + } + c.canon.Set(T, T) + return T +} diff --git a/tools/vendor/golang.org/x/tools/go/ssa/wrappers.go b/tools/vendor/golang.org/x/tools/go/ssa/wrappers.go index a4ae71d8..90ddc9df 100644 --- a/tools/vendor/golang.org/x/tools/go/ssa/wrappers.go +++ b/tools/vendor/golang.org/x/tools/go/ssa/wrappers.go @@ -72,6 +72,7 @@ func makeWrapper(prog *Program, sel *types.Selection) *Function { Synthetic: description, Prog: prog, pos: obj.Pos(), + info: nil, // info is not set on wrappers. } fn.startBody() fn.addSpilledParam(recv) @@ -190,6 +191,7 @@ func makeBound(prog *Program, obj *types.Func) *Function { Synthetic: description, Prog: prog, pos: obj.Pos(), + info: nil, // info is not set on wrappers. } fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn} @@ -246,9 +248,11 @@ func makeThunk(prog *Program, sel *types.Selection) *Function { panic(sel) } + // Canonicalize sel.Recv() to avoid constructing duplicate thunks. + canonRecv := prog.canon.Type(sel.Recv()) key := selectionKey{ kind: sel.Kind(), - recv: sel.Recv(), + recv: canonRecv, obj: sel.Obj(), index: fmt.Sprint(sel.Index()), indirect: sel.Indirect(), @@ -257,14 +261,6 @@ func makeThunk(prog *Program, sel *types.Selection) *Function { prog.methodsMu.Lock() defer prog.methodsMu.Unlock() - // Canonicalize key.recv to avoid constructing duplicate thunks. - canonRecv, ok := prog.canon.At(key.recv).(types.Type) - if !ok { - canonRecv = key.recv - prog.canon.Set(key.recv, canonRecv) - } - key.recv = canonRecv - fn, ok := prog.thunks[key] if !ok { fn = makeWrapper(prog, sel) diff --git a/tools/vendor/golang.org/x/tools/go/types/typeutil/map.go b/tools/vendor/golang.org/x/tools/go/types/typeutil/map.go index 490ee904..c9f8f25a 100644 --- a/tools/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ b/tools/vendor/golang.org/x/tools/go/types/typeutil/map.go @@ -379,7 +379,7 @@ func (h Hasher) hashFor(t types.Type) uint32 { func (h Hasher) hashTuple(tuple *types.Tuple) uint32 { // See go/types.identicalTypes for rationale. n := tuple.Len() - var hash uint32 = 9137 + 2*uint32(n) + hash := 9137 + 2*uint32(n) for i := 0; i < n; i++ { hash += 3 * h.Hash(tuple.At(i).Type()) } @@ -398,7 +398,7 @@ func (h Hasher) hashUnion(t *typeparams.Union) uint32 { } func (h Hasher) hashTermSet(terms []*typeparams.Term) uint32 { - var hash uint32 = 9157 + 2*uint32(len(terms)) + hash := 9157 + 2*uint32(len(terms)) for _, term := range terms { // term order is not significant. termHash := h.Hash(term.Type()) @@ -416,14 +416,16 @@ func (h Hasher) hashTermSet(terms []*typeparams.Term) uint32 { // If h.sigTParams is set and contains t, then we are in the process of hashing // a signature, and the hash value of t must depend only on t's index and // constraint: signatures are considered identical modulo type parameter -// renaming. +// renaming. To avoid infinite recursion, we only hash the type parameter +// index, and rely on types.Identical to handle signatures where constraints +// are not identical. // // Otherwise the hash of t depends only on t's pointer identity. func (h Hasher) hashTypeParam(t *typeparams.TypeParam) uint32 { if h.sigTParams != nil { i := t.Index() if i >= 0 && i < h.sigTParams.Len() && t == h.sigTParams.At(i) { - return 9173 + 2*h.Hash(t.Constraint()) + 3*uint32(i) + return 9173 + 3*uint32(i) } } return h.hashPtr(t.Obj()) diff --git a/tools/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go b/tools/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go index 01f6e829..78ee2c06 100644 --- a/tools/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go +++ b/tools/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go @@ -17,6 +17,9 @@ import ( "golang.org/x/tools/internal/lsp/fuzzy" ) +// Flag to gate diagnostics for fuzz tests in 1.18. +var DiagnoseFuzzTests bool = false + var ( GetTypeErrors func(p interface{}) []types.Error SetTypeErrors func(p interface{}, errors []types.Error) diff --git a/tools/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/tools/vendor/golang.org/x/tools/internal/gocommand/invoke.go index 8659a0c5..f7533683 100644 --- a/tools/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/tools/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -9,7 +9,6 @@ import ( "bytes" "context" "fmt" - exec "golang.org/x/sys/execabs" "io" "os" "regexp" @@ -18,6 +17,8 @@ import ( "sync" "time" + exec "golang.org/x/sys/execabs" + "golang.org/x/tools/internal/event" ) @@ -131,9 +132,16 @@ type Invocation struct { Verb string Args []string BuildFlags []string - ModFlag string - ModFile string - Overlay string + + // If ModFlag is set, the go command is invoked with -mod=ModFlag. + ModFlag string + + // If ModFile is set, the go command is invoked with -modfile=ModFile. + ModFile string + + // If Overlay is set, the go command is invoked with -overlay=Overlay. + Overlay string + // If CleanEnv is set, the invocation will run only with the environment // in Env, not starting with os.Environ. CleanEnv bool diff --git a/tools/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/tools/vendor/golang.org/x/tools/internal/gocommand/vendor.go index 5e75bd6d..2d3d408c 100644 --- a/tools/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ b/tools/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -38,10 +38,10 @@ var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) // with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, // of which only Verb and Args are modified to run the appropriate Go command. // Inspired by setDefaultBuildMod in modload/init.go -func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { +func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) if err != nil { - return nil, false, err + return false, nil, err } // We check the GOFLAGS to see if there is anything overridden or not. @@ -49,7 +49,7 @@ func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, inv.Args = []string{"GOFLAGS"} stdout, err := r.Run(ctx, inv) if err != nil { - return nil, false, err + return false, nil, err } goflags := string(bytes.TrimSpace(stdout.Bytes())) matches := modFlagRegexp.FindStringSubmatch(goflags) @@ -57,25 +57,27 @@ func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, if len(matches) != 0 { modFlag = matches[1] } - if modFlag != "" { - // Don't override an explicit '-mod=' argument. - return mainMod, modFlag == "vendor", nil + // Don't override an explicit '-mod=' argument. + if modFlag == "vendor" { + return true, mainMod, nil + } else if modFlag != "" { + return false, nil, nil } if mainMod == nil || !go114 { - return mainMod, false, nil + return false, nil, nil } // Check 1.14's automatic vendor mode. if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { // The Go version is at least 1.14, and a vendor directory exists. // Set -mod=vendor by default. - return mainMod, true, nil + return true, mainMod, nil } } - return mainMod, false, nil + return false, nil, nil } -// getMainModuleAnd114 gets the main module's information and whether the +// getMainModuleAnd114 gets one of the main modules' information and whether the // go command in use is 1.14+. This is the information needed to figure out // if vendoring should be enabled. func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { diff --git a/tools/vendor/golang.org/x/tools/internal/imports/imports.go b/tools/vendor/golang.org/x/tools/internal/imports/imports.go index 2815edc3..25973989 100644 --- a/tools/vendor/golang.org/x/tools/internal/imports/imports.go +++ b/tools/vendor/golang.org/x/tools/internal/imports/imports.go @@ -306,7 +306,7 @@ func matchSpace(orig []byte, src []byte) []byte { return b.Bytes() } -var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+)"`) +var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+?)"`) func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) { var out bytes.Buffer diff --git a/tools/vendor/golang.org/x/tools/internal/imports/mod.go b/tools/vendor/golang.org/x/tools/internal/imports/mod.go index dff6d553..2bcf41f5 100644 --- a/tools/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/tools/vendor/golang.org/x/tools/internal/imports/mod.go @@ -34,7 +34,8 @@ type ModuleResolver struct { scannedRoots map[gopathwalk.Root]bool initialized bool - main *gocommand.ModuleJSON + mains []*gocommand.ModuleJSON + mainByDir map[string]*gocommand.ModuleJSON modsByModPath []*gocommand.ModuleJSON // All modules, ordered by # of path components in module Path... modsByDir []*gocommand.ModuleJSON // ...or Dir. @@ -69,21 +70,21 @@ func (r *ModuleResolver) init() error { Logf: r.env.Logf, WorkingDir: r.env.WorkingDir, } - mainMod, vendorEnabled, err := gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) + vendorEnabled, mainModVendor, err := gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) if err != nil { return err } - if mainMod != nil && vendorEnabled { + if mainModVendor != nil && vendorEnabled { // Vendor mode is on, so all the non-Main modules are irrelevant, // and we need to search /vendor for everything. - r.main = mainMod + r.mains = []*gocommand.ModuleJSON{mainModVendor} r.dummyVendorMod = &gocommand.ModuleJSON{ Path: "", - Dir: filepath.Join(mainMod.Dir, "vendor"), + Dir: filepath.Join(mainModVendor.Dir, "vendor"), } - r.modsByModPath = []*gocommand.ModuleJSON{mainMod, r.dummyVendorMod} - r.modsByDir = []*gocommand.ModuleJSON{mainMod, r.dummyVendorMod} + r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} + r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} } else { // Vendor mode is off, so run go list -m ... to find everything. err := r.initAllMods() @@ -122,8 +123,10 @@ func (r *ModuleResolver) init() error { r.roots = []gopathwalk.Root{ {filepath.Join(goenv["GOROOT"], "/src"), gopathwalk.RootGOROOT}, } - if r.main != nil { - r.roots = append(r.roots, gopathwalk.Root{r.main.Dir, gopathwalk.RootCurrentModule}) + r.mainByDir = make(map[string]*gocommand.ModuleJSON) + for _, main := range r.mains { + r.roots = append(r.roots, gopathwalk.Root{main.Dir, gopathwalk.RootCurrentModule}) + r.mainByDir[main.Dir] = main } if vendorEnabled { r.roots = append(r.roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther}) @@ -189,7 +192,7 @@ func (r *ModuleResolver) initAllMods() error { r.modsByModPath = append(r.modsByModPath, mod) r.modsByDir = append(r.modsByDir, mod) if mod.Main { - r.main = mod + r.mains = append(r.mains, mod) } } return nil @@ -609,7 +612,7 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir } switch root.Type { case gopathwalk.RootCurrentModule: - importPath = path.Join(r.main.Path, filepath.ToSlash(subdir)) + importPath = path.Join(r.mainByDir[root.Path].Path, filepath.ToSlash(subdir)) case gopathwalk.RootModuleCache: matches := modCacheRegexp.FindStringSubmatch(subdir) if len(matches) == 0 { diff --git a/tools/vendor/golang.org/x/tools/internal/typeparams/common.go b/tools/vendor/golang.org/x/tools/internal/typeparams/common.go index 1222764b..ab6b30b8 100644 --- a/tools/vendor/golang.org/x/tools/internal/typeparams/common.go +++ b/tools/vendor/golang.org/x/tools/internal/typeparams/common.go @@ -77,3 +77,104 @@ func IsTypeParam(t types.Type) bool { _, ok := t.(*TypeParam) return ok } + +// OriginMethod returns the origin method associated with the method fn. +// For methods on a non-generic receiver base type, this is just +// fn. However, for methods with a generic receiver, OriginMethod returns the +// corresponding method in the method set of the origin type. +// +// As a special case, if fn is not a method (has no receiver), OriginMethod +// returns fn. +func OriginMethod(fn *types.Func) *types.Func { + recv := fn.Type().(*types.Signature).Recv() + if recv == nil { + + return fn + } + base := recv.Type() + p, isPtr := base.(*types.Pointer) + if isPtr { + base = p.Elem() + } + named, isNamed := base.(*types.Named) + if !isNamed { + // Receiver is a *types.Interface. + return fn + } + if ForNamed(named).Len() == 0 { + // Receiver base has no type parameters, so we can avoid the lookup below. + return fn + } + orig := NamedTypeOrigin(named) + gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) + return gfn.(*types.Func) +} + +// GenericAssignableTo is a generalization of types.AssignableTo that +// implements the following rule for uninstantiated generic types: +// +// If V and T are generic named types, then V is considered assignable to T if, +// for every possible instantation of V[A_1, ..., A_N], the instantiation +// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. +// +// If T has structural constraints, they must be satisfied by V. +// +// For example, consider the following type declarations: +// +// type Interface[T any] interface { +// Accept(T) +// } +// +// type Container[T any] struct { +// Element T +// } +// +// func (c Container[T]) Accept(t T) { c.Element = t } +// +// In this case, GenericAssignableTo reports that instantiations of Container +// are assignable to the corresponding instantiation of Interface. +func GenericAssignableTo(ctxt *Context, V, T types.Type) bool { + // If V and T are not both named, or do not have matching non-empty type + // parameter lists, fall back on types.AssignableTo. + + VN, Vnamed := V.(*types.Named) + TN, Tnamed := T.(*types.Named) + if !Vnamed || !Tnamed { + return types.AssignableTo(V, T) + } + + vtparams := ForNamed(VN) + ttparams := ForNamed(TN) + if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 { + return types.AssignableTo(V, T) + } + + // V and T have the same (non-zero) number of type params. Instantiate both + // with the type parameters of V. This must always succeed for V, and will + // succeed for T if and only if the type set of each type parameter of V is a + // subset of the type set of the corresponding type parameter of T, meaning + // that every instantiation of V corresponds to a valid instantiation of T. + + // Minor optimization: ensure we share a context across the two + // instantiations below. + if ctxt == nil { + ctxt = NewContext() + } + + var targs []types.Type + for i := 0; i < vtparams.Len(); i++ { + targs = append(targs, vtparams.At(i)) + } + + vinst, err := Instantiate(ctxt, V, targs, true) + if err != nil { + panic("type parameters should satisfy their own constraints") + } + + tinst, err := Instantiate(ctxt, T, targs, true) + if err != nil { + return false + } + + return types.AssignableTo(vinst, tinst) +} diff --git a/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go index 5fd3fc35..b4788978 100644 --- a/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go +++ b/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go @@ -185,6 +185,11 @@ func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil } // this Go version. type Context struct{} +// NewContext returns a placeholder Context instance. +func NewContext() *Context { + return &Context{} +} + // Instantiate is unsupported on this Go version, and panics. func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { unsupported() diff --git a/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go index 7470aed8..114a36b8 100644 --- a/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go +++ b/tools/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go @@ -140,6 +140,11 @@ func GetInstances(info *types.Info) map[*ast.Ident]Instance { // Context is an alias for types.Context. type Context = types.Context +// NewContext calls types.NewContext. +func NewContext() *Context { + return types.NewContext() +} + // Instantiate calls types.Instantiate. func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { return types.Instantiate(ctxt, typ, targs, validate) diff --git a/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go index fa2834e2..d38ee3c2 100644 --- a/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ b/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go @@ -1365,4 +1365,162 @@ const ( // return i // } InvalidGo + + // All codes below were added in Go 1.17. + + /* decl */ + + // BadDecl occurs when a declaration has invalid syntax. + BadDecl + + // RepeatedDecl occurs when an identifier occurs more than once on the left + // hand side of a short variable declaration. + // + // Example: + // func _() { + // x, y, y := 1, 2, 3 + // } + RepeatedDecl + + /* unsafe */ + + // InvalidUnsafeAdd occurs when unsafe.Add is called with a + // length argument that is not of integer type. + // + // Example: + // import "unsafe" + // + // var p unsafe.Pointer + // var _ = unsafe.Add(p, float64(1)) + InvalidUnsafeAdd + + // InvalidUnsafeSlice occurs when unsafe.Slice is called with a + // pointer argument that is not of pointer type or a length argument + // that is not of integer type, negative, or out of bounds. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(x, 1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, float64(1)) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, -1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, uint64(1) << 63) + InvalidUnsafeSlice + + // All codes below were added in Go 1.18. + + /* features */ + + // UnsupportedFeature occurs when a language feature is used that is not + // supported at this Go version. + UnsupportedFeature + + /* type params */ + + // NotAGenericType occurs when a non-generic type is used where a generic + // type is expected: in type or function instantiation. + // + // Example: + // type T int + // + // var _ T[int] + NotAGenericType + + // WrongTypeArgCount occurs when a type or function is instantiated with an + // incorrent number of type arguments, including when a generic type or + // function is used without instantiation. + // + // Errors inolving failed type inference are assigned other error codes. + // + // Example: + // type T[p any] int + // + // var _ T[int, string] + // + // Example: + // func f[T any]() {} + // + // var x = f + WrongTypeArgCount + + // CannotInferTypeArgs occurs when type or function type argument inference + // fails to infer all type arguments. + // + // Example: + // func f[T any]() {} + // + // func _() { + // f() + // } + // + // Example: + // type N[P, Q any] struct{} + // + // var _ N[int] + CannotInferTypeArgs + + // InvalidTypeArg occurs when a type argument does not satisfy its + // corresponding type parameter constraints. + // + // Example: + // type T[P ~int] struct{} + // + // var _ T[string] + InvalidTypeArg // arguments? InferenceFailed + + // InvalidInstanceCycle occurs when an invalid cycle is detected + // within the instantiation graph. + // + // Example: + // func f[T any]() { f[*T]() } + InvalidInstanceCycle + + // InvalidUnion occurs when an embedded union or approximation element is + // not valid. + // + // Example: + // type _ interface { + // ~int | interface{ m() } + // } + InvalidUnion + + // MisplacedConstraintIface occurs when a constraint-type interface is used + // outside of constraint position. + // + // Example: + // type I interface { ~int } + // + // var _ I + MisplacedConstraintIface + + // InvalidMethodTypeParams occurs when methods have type parameters. + // + // It cannot be encountered with an AST parsed using go/parser. + InvalidMethodTypeParams + + // MisplacedTypeParam occurs when a type parameter is used in a place where + // it is not permitted. + // + // Example: + // type T[P any] P + // + // Example: + // type T[P any] struct{ *P } + MisplacedTypeParam ) diff --git a/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go index 3e5842a5..de90e951 100644 --- a/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go +++ b/tools/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go @@ -138,11 +138,25 @@ func _() { _ = x[UnusedResults-128] _ = x[InvalidDefer-129] _ = x[InvalidGo-130] + _ = x[BadDecl-131] + _ = x[RepeatedDecl-132] + _ = x[InvalidUnsafeAdd-133] + _ = x[InvalidUnsafeSlice-134] + _ = x[UnsupportedFeature-135] + _ = x[NotAGenericType-136] + _ = x[WrongTypeArgCount-137] + _ = x[CannotInferTypeArgs-138] + _ = x[InvalidTypeArg-139] + _ = x[InvalidInstanceCycle-140] + _ = x[InvalidUnion-141] + _ = x[MisplacedConstraintIface-142] + _ = x[InvalidMethodTypeParams-143] + _ = x[MisplacedTypeParam-144] } -const _ErrorCode_name = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGo" +const _ErrorCode_name = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParam" -var _ErrorCode_index = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 215, 231, 250, 258, 274, 292, 309, 327, 351, 359, 374, 390, 408, 425, 440, 447, 458, 481, 496, 508, 519, 534, 548, 563, 578, 591, 600, 614, 629, 640, 655, 664, 680, 700, 718, 737, 749, 768, 787, 803, 820, 839, 853, 864, 879, 892, 907, 923, 937, 953, 968, 985, 1003, 1018, 1028, 1038, 1055, 1077, 1091, 1105, 1125, 1143, 1163, 1181, 1204, 1220, 1235, 1248, 1258, 1270, 1281, 1295, 1308, 1319, 1329, 1344, 1355, 1366, 1379, 1395, 1412, 1436, 1453, 1468, 1478, 1487, 1500, 1516, 1532, 1543, 1558, 1574, 1588, 1604, 1618, 1635, 1655, 1668, 1684, 1698, 1715, 1732, 1749, 1764, 1778, 1792, 1803, 1815, 1828, 1845, 1858, 1869, 1882, 1894, 1903} +var _ErrorCode_index = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 215, 231, 250, 258, 274, 292, 309, 327, 351, 359, 374, 390, 408, 425, 440, 447, 458, 481, 496, 508, 519, 534, 548, 563, 578, 591, 600, 614, 629, 640, 655, 664, 680, 700, 718, 737, 749, 768, 787, 803, 820, 839, 853, 864, 879, 892, 907, 923, 937, 953, 968, 985, 1003, 1018, 1028, 1038, 1055, 1077, 1091, 1105, 1125, 1143, 1163, 1181, 1204, 1220, 1235, 1248, 1258, 1270, 1281, 1295, 1308, 1319, 1329, 1344, 1355, 1366, 1379, 1395, 1412, 1436, 1453, 1468, 1478, 1487, 1500, 1516, 1532, 1543, 1558, 1574, 1588, 1604, 1618, 1635, 1655, 1668, 1684, 1698, 1715, 1732, 1749, 1764, 1778, 1792, 1803, 1815, 1828, 1845, 1858, 1869, 1882, 1894, 1903, 1910, 1922, 1938, 1956, 1974, 1989, 2006, 2025, 2039, 2059, 2071, 2095, 2118, 2136} func (i ErrorCode) String() string { i -= 1 diff --git a/tools/vendor/golang.org/x/tools/internal/typesinternal/types.go b/tools/vendor/golang.org/x/tools/internal/typesinternal/types.go index 7c77c2fb..ce7d4351 100644 --- a/tools/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/tools/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -48,3 +48,5 @@ func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, } return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true } + +var SetGoVersion = func(conf *types.Config, version string) bool { return false } diff --git a/tools/vendor/golang.org/x/tools/internal/typesinternal/types_118.go b/tools/vendor/golang.org/x/tools/internal/typesinternal/types_118.go new file mode 100644 index 00000000..a42b072a --- /dev/null +++ b/tools/vendor/golang.org/x/tools/internal/typesinternal/types_118.go @@ -0,0 +1,19 @@ +// Copyright 2021 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.18 +// +build go1.18 + +package typesinternal + +import ( + "go/types" +) + +func init() { + SetGoVersion = func(conf *types.Config, version string) bool { + conf.GoVersion = version + return true + } +} diff --git a/tools/vendor/modules.txt b/tools/vendor/modules.txt index a90c9233..d80d019f 100644 --- a/tools/vendor/modules.txt +++ b/tools/vendor/modules.txt @@ -1273,7 +1273,7 @@ golang.org/x/crypto/ssh golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/knownhosts -# golang.org/x/mod v0.5.1 +# golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 ## explicit; go 1.17 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile @@ -1326,7 +1326,7 @@ golang.org/x/text/width # golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.1.9 +# golang.org/x/tools v0.1.10 ## explicit; go 1.17 golang.org/x/tools/cmd/cover golang.org/x/tools/cmd/goimports