summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/tools/go/internal
diff options
context:
space:
mode:
authorWim <wim@42.be>2022-04-01 00:23:19 +0200
committerGitHub <noreply@github.com>2022-04-01 00:23:19 +0200
commitc6716e030c02f316b887c1d3ee4b443aa3ab6afd (patch)
tree470461fe2d29662e7a69834ed21fce30beed65ab /vendor/golang.org/x/tools/go/internal
parent4ab72acec656dafd304f88359b509b1f27c06604 (diff)
downloadmatterbridge-msglm-c6716e030c02f316b887c1d3ee4b443aa3ab6afd.tar.gz
matterbridge-msglm-c6716e030c02f316b887c1d3ee4b443aa3ab6afd.tar.bz2
matterbridge-msglm-c6716e030c02f316b887c1d3ee4b443aa3ab6afd.zip
Update dependencies (#1784)
Diffstat (limited to 'vendor/golang.org/x/tools/go/internal')
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go3
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go51
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go16
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go12
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go172
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go166
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go4
-rw-r--r--vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go7
8 files changed, 291 insertions, 140 deletions
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
index 072005af..0a3cdb9a 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
@@ -34,9 +34,6 @@ import (
// (suspected) format errors, and whenever a change is made to the format.
const debugFormat = false // default: false
-// If trace is set, debugging output is printed to std out.
-const trace = false // default: false
-
// Current export format version. Increase with each format change.
// Note: The latest binary (non-indexed) export format is at version 6.
// This exporter is still at level 4, but it doesn't matter since
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
index b0231200..b85de014 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
@@ -74,9 +74,10 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []
pathList: []string{""}, // empty string is mapped to 0
fake: fakeFileSet{
fset: fset,
- files: make(map[string]*token.File),
+ files: make(map[string]*fileInfo),
},
}
+ defer p.fake.setLines() // set lines for files in fset
// read version info
var versionstr string
@@ -338,37 +339,49 @@ func (p *importer) pos() token.Pos {
// Synthesize a token.Pos
type fakeFileSet struct {
fset *token.FileSet
- files map[string]*token.File
+ files map[string]*fileInfo
}
+type fileInfo struct {
+ file *token.File
+ lastline int
+}
+
+const maxlines = 64 * 1024
+
func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
// TODO(mdempsky): Make use of column.
- // Since we don't know the set of needed file positions, we
- // reserve maxlines positions per file.
- const maxlines = 64 * 1024
+ // Since we don't know the set of needed file positions, we reserve maxlines
+ // positions per file. We delay calling token.File.SetLines until all
+ // positions have been calculated (by way of fakeFileSet.setLines), so that
+ // we can avoid setting unnecessary lines. See also golang/go#46586.
f := s.files[file]
if f == nil {
- f = s.fset.AddFile(file, -1, maxlines)
+ f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
s.files[file] = f
- // Allocate the fake linebreak indices on first use.
- // TODO(adonovan): opt: save ~512KB using a more complex scheme?
- fakeLinesOnce.Do(func() {
- fakeLines = make([]int, maxlines)
- for i := range fakeLines {
- fakeLines[i] = i
- }
- })
- f.SetLines(fakeLines)
}
-
if line > maxlines {
line = 1
}
+ if line > f.lastline {
+ f.lastline = line
+ }
- // Treat the file as if it contained only newlines
- // and column=1: use the line number as the offset.
- return f.Pos(line - 1)
+ // Return a fake position assuming that f.file consists only of newlines.
+ return token.Pos(f.file.Base() + line - 1)
+}
+
+func (s *fakeFileSet) setLines() {
+ fakeLinesOnce.Do(func() {
+ fakeLines = make([]int, maxlines)
+ for i := range fakeLines {
+ fakeLines[i] = i
+ }
+ })
+ for _, f := range s.files {
+ f.file.SetLines(fakeLines[:f.lastline])
+ }
}
var (
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
index f33dc561..f6437feb 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
@@ -16,7 +16,7 @@ import (
"strings"
)
-func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
+func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) {
// See $GOROOT/include/ar.h.
hdr := make([]byte, 16+12+6+6+8+10+2)
_, err = io.ReadFull(r, hdr)
@@ -28,7 +28,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
fmt.Printf("header: %s", hdr)
}
s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
- size, err = strconv.Atoi(s)
+ length, err := strconv.Atoi(s)
+ size = int64(length)
if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
err = fmt.Errorf("invalid archive header")
return
@@ -42,8 +43,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
// file by reading from it. The reader must be positioned at the
// start of the file before calling this function. The hdr result
// is the string before the export data, either "$$" or "$$B".
-//
-func FindExportData(r *bufio.Reader) (hdr string, err error) {
+// The size result is the length of the export data in bytes, or -1 if not known.
+func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
// Read first line to make sure this is an object file.
line, err := r.ReadSlice('\n')
if err != nil {
@@ -54,7 +55,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
if string(line) == "!<arch>\n" {
// Archive file. Scan to __.PKGDEF.
var name string
- if name, _, err = readGopackHeader(r); err != nil {
+ if name, size, err = readGopackHeader(r); err != nil {
return
}
@@ -70,6 +71,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
+ size -= int64(len(line))
}
// Now at __.PKGDEF in archive or still at beginning of file.
@@ -86,8 +88,12 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
+ size -= int64(len(line))
}
hdr = string(line)
+ if size < 0 {
+ size = -1
+ }
return
}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
index e8cba6b2..3ab66830 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
@@ -29,8 +29,14 @@ import (
"text/scanner"
)
-// debugging/development support
-const debug = false
+const (
+ // Enable debug during development: it adds some additional checks, and
+ // prevents errors from being recovered.
+ debug = false
+
+ // If trace is set, debugging output is printed to std out.
+ trace = false
+)
var pkgExts = [...]string{".a", ".o"}
@@ -179,7 +185,7 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
var hdr string
buf := bufio.NewReader(rc)
- if hdr, err = FindExportData(buf); err != nil {
+ if hdr, _, err = FindExportData(buf); err != nil {
return
}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
index be8b7459..20955340 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
@@ -11,6 +11,7 @@ package gcimporter
import (
"bytes"
"encoding/binary"
+ "fmt"
"go/ast"
"go/constant"
"go/token"
@@ -19,6 +20,8 @@ import (
"math/big"
"reflect"
"sort"
+ "strconv"
+ "strings"
"golang.org/x/tools/internal/typeparams"
)
@@ -33,15 +36,15 @@ const bundleVersion = 0
// The package path of the top-level package will not be recorded,
// so that calls to IImportData can override with a provided package path.
func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
- return iexportCommon(out, fset, false, []*types.Package{pkg})
+ return iexportCommon(out, fset, false, iexportVersion, []*types.Package{pkg})
}
// IExportBundle writes an indexed export bundle for pkgs to out.
func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
- return iexportCommon(out, fset, true, pkgs)
+ return iexportCommon(out, fset, true, iexportVersion, pkgs)
}
-func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*types.Package) (err error) {
+func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, version int, pkgs []*types.Package) (err error) {
if !debug {
defer func() {
if e := recover(); e != nil {
@@ -57,9 +60,11 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
p := iexporter{
fset: fset,
+ version: version,
allPkgs: map[*types.Package]bool{},
stringIndex: map[string]uint64{},
declIndex: map[types.Object]uint64{},
+ tparamNames: map[types.Object]string{},
typIndex: map[types.Type]uint64{},
}
if !bundle {
@@ -119,7 +124,7 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
if bundle {
hdr.uint64(bundleVersion)
}
- hdr.uint64(iexportVersion)
+ hdr.uint64(uint64(p.version))
hdr.uint64(uint64(p.strings.Len()))
hdr.uint64(dataLen)
@@ -136,8 +141,12 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
// non-compiler tools and includes a complete package description
// (i.e., name and height).
func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
+ type pkgObj struct {
+ obj types.Object
+ name string // qualified name; differs from obj.Name for type params
+ }
// Build a map from packages to objects from that package.
- pkgObjs := map[*types.Package][]types.Object{}
+ pkgObjs := map[*types.Package][]pkgObj{}
// For the main index, make sure to include every package that
// we reference, even if we're not exporting (or reexporting)
@@ -150,7 +159,8 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
}
for obj := range index {
- pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj)
+ name := w.p.exportName(obj)
+ pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name})
}
var pkgs []*types.Package
@@ -158,7 +168,7 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
pkgs = append(pkgs, pkg)
sort.Slice(objs, func(i, j int) bool {
- return indexName(objs[i]) < indexName(objs[j])
+ return objs[i].name < objs[j].name
})
}
@@ -175,29 +185,25 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
objs := pkgObjs[pkg]
w.uint64(uint64(len(objs)))
for _, obj := range objs {
- w.string(indexName(obj))
- w.uint64(index[obj])
+ w.string(obj.name)
+ w.uint64(index[obj.obj])
}
}
}
-// indexName returns the 'indexed' name of an object. It differs from
-// obj.Name() only for type parameter names, where we include the subscripted
-// type parameter ID.
-//
-// TODO(rfindley): remove this once we no longer need subscripts.
-func indexName(obj types.Object) (res string) {
- if _, ok := obj.(*types.TypeName); ok {
- if tparam, ok := obj.Type().(*typeparams.TypeParam); ok {
- return types.TypeString(tparam, func(*types.Package) string { return "" })
- }
+// exportName returns the 'exported' name of an object. It differs from
+// obj.Name() only for type parameters (see tparamExportName for details).
+func (p *iexporter) exportName(obj types.Object) (res string) {
+ if name := p.tparamNames[obj]; name != "" {
+ return name
}
return obj.Name()
}
type iexporter struct {
- fset *token.FileSet
- out *bytes.Buffer
+ fset *token.FileSet
+ out *bytes.Buffer
+ version int
localpkg *types.Package
@@ -211,9 +217,21 @@ type iexporter struct {
strings intWriter
stringIndex map[string]uint64
- data0 intWriter
- declIndex map[types.Object]uint64
- typIndex map[types.Type]uint64
+ data0 intWriter
+ declIndex map[types.Object]uint64
+ tparamNames map[types.Object]string // typeparam->exported name
+ typIndex map[types.Type]uint64
+
+ indent int // for tracing support
+}
+
+func (p *iexporter) trace(format string, args ...interface{}) {
+ if !trace {
+ // Call sites should also be guarded, but having this check here allows
+ // easily enabling/disabling debug trace statements.
+ return
+ }
+ fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
}
// stringOff returns the offset of s within the string section.
@@ -239,7 +257,7 @@ func (p *iexporter) pushDecl(obj types.Object) {
return
}
- p.declIndex[obj] = ^uint64(0) // mark n present in work queue
+ p.declIndex[obj] = ^uint64(0) // mark obj present in work queue
p.declTodo.pushTail(obj)
}
@@ -262,6 +280,14 @@ func (w *exportWriter) exportPath(pkg *types.Package) string {
}
func (p *iexporter) doDecl(obj types.Object) {
+ if trace {
+ p.trace("exporting decl %v (%T)", obj, obj)
+ p.indent++
+ defer func() {
+ p.indent--
+ p.trace("=> %s", obj)
+ }()
+ }
w := p.newWriter()
w.setPkg(obj.Pkg(), false)
@@ -284,14 +310,15 @@ func (p *iexporter) doDecl(obj types.Object) {
w.tag('G')
}
w.pos(obj.Pos())
- // The tparam list of the function type is the
- // declaration of the type params. So, write out the type
- // params right now. Then those type params will be
- // referenced via their type offset (via typOff) in all
- // other places in the signature and function that they
- // are used.
+ // The tparam list of the function type is the declaration of the type
+ // params. So, write out the type params right now. Then those type params
+ // will be referenced via their type offset (via typOff) in all other
+ // places in the signature and function where they are used.
+ //
+ // While importing the type parameters, tparamList computes and records
+ // their export name, so that it can be later used when writing the index.
if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
- w.tparamList(tparams, obj.Pkg())
+ w.tparamList(obj.Name(), tparams, obj.Pkg())
}
w.signature(sig)
@@ -306,7 +333,15 @@ func (p *iexporter) doDecl(obj types.Object) {
if tparam, ok := t.(*typeparams.TypeParam); ok {
w.tag('P')
w.pos(obj.Pos())
- w.typ(tparam.Constraint(), obj.Pkg())
+ constraint := tparam.Constraint()
+ if p.version >= iexportVersionGo1_18 {
+ implicit := false
+ if iface, _ := constraint.(*types.Interface); iface != nil {
+ implicit = typeparams.IsImplicit(iface)
+ }
+ w.bool(implicit)
+ }
+ w.typ(constraint, obj.Pkg())
break
}
@@ -331,7 +366,9 @@ func (p *iexporter) doDecl(obj types.Object) {
w.pos(obj.Pos())
if typeparams.ForNamed(named).Len() > 0 {
- w.tparamList(typeparams.ForNamed(named), obj.Pkg())
+ // While importing the type parameters, tparamList computes and records
+ // their export name, so that it can be later used when writing the index.
+ w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
}
underlying := obj.Type().Underlying()
@@ -348,6 +385,17 @@ func (p *iexporter) doDecl(obj types.Object) {
w.pos(m.Pos())
w.string(m.Name())
sig, _ := m.Type().(*types.Signature)
+
+ // Receiver type parameters are type arguments of the receiver type, so
+ // their name must be qualified before exporting recv.
+ if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
+ prefix := obj.Name() + "." + m.Name()
+ for i := 0; i < rparams.Len(); i++ {
+ rparam := rparams.At(i)
+ name := tparamExportName(prefix, rparam)
+ w.p.tparamNames[rparam.Obj()] = name
+ }
+ }
w.param(sig.Recv())
w.signature(sig)
}
@@ -364,7 +412,7 @@ func (w *exportWriter) tag(tag byte) {
}
func (w *exportWriter) pos(pos token.Pos) {
- if iexportVersion >= iexportVersionPosCol {
+ if w.p.version >= iexportVersionPosCol {
w.posV1(pos)
} else {
w.posV0(pos)
@@ -447,9 +495,11 @@ func (w *exportWriter) pkg(pkg *types.Package) {
}
func (w *exportWriter) qualifiedIdent(obj types.Object) {
+ name := w.p.exportName(obj)
+
// Ensure any referenced declarations are written out too.
w.p.pushDecl(obj)
- w.string(indexName(obj))
+ w.string(name)
w.pkg(obj.Pkg())
}
@@ -483,6 +533,14 @@ func (w *exportWriter) startType(k itag) {
}
func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
+ if trace {
+ w.p.trace("exporting type %s (%T)", t, t)
+ w.p.indent++
+ defer func() {
+ w.p.indent--
+ w.p.trace("=> %s", t)
+ }()
+ }
switch t := t.(type) {
case *types.Named:
if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
@@ -619,14 +677,49 @@ func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
}
}
-func (w *exportWriter) tparamList(list *typeparams.TypeParamList, pkg *types.Package) {
+func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
ll := uint64(list.Len())
w.uint64(ll)
for i := 0; i < list.Len(); i++ {
+ tparam := list.At(i)
+ // Set the type parameter exportName before exporting its type.
+ exportName := tparamExportName(prefix, tparam)
+ w.p.tparamNames[tparam.Obj()] = exportName
w.typ(list.At(i), pkg)
}
}
+const blankMarker = "$"
+
+// tparamExportName returns the 'exported' name of a type parameter, which
+// differs from its actual object name: it is prefixed with a qualifier, and
+// blank type parameter names are disambiguated by their index in the type
+// parameter list.
+func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
+ assert(prefix != "")
+ name := tparam.Obj().Name()
+ if name == "_" {
+ name = blankMarker + strconv.Itoa(tparam.Index())
+ }
+ return prefix + "." + name
+}
+
+// tparamName returns the real name of a type parameter, after stripping its
+// qualifying prefix and reverting blank-name encoding. See tparamExportName
+// for details.
+func tparamName(exportName string) string {
+ // Remove the "path" from the type param name that makes it unique.
+ ix := strings.LastIndex(exportName, ".")
+ if ix < 0 {
+ errorf("malformed type parameter export name %s: missing prefix", exportName)
+ }
+ name := exportName[ix+1:]
+ if strings.HasPrefix(name, blankMarker) {
+ return "_"
+ }
+ return name
+}
+
func (w *exportWriter) paramList(tup *types.Tuple) {
n := tup.Len()
w.uint64(uint64(n))
@@ -643,6 +736,9 @@ func (w *exportWriter) param(obj types.Object) {
func (w *exportWriter) value(typ types.Type, v constant.Value) {
w.typ(typ, nil)
+ if w.p.version >= iexportVersionGo1_18 {
+ w.int64(int64(v.Kind()))
+ }
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
case types.IsBoolean:
@@ -832,7 +928,7 @@ func (w *exportWriter) localIdent(obj types.Object) {
return
}
- name := indexName(obj)
+ name := obj.Name()
if name == "_" {
w.string("_")
return
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
index 1fcc87e5..1a33cd5c 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
@@ -18,6 +18,7 @@ import (
"go/types"
"io"
"sort"
+ "strings"
"golang.org/x/tools/internal/typeparams"
)
@@ -45,12 +46,10 @@ func (r *intReader) uint64() uint64 {
// Keep this in sync with constants in iexport.go.
const (
- iexportVersionGo1_11 = 0
- iexportVersionPosCol = 1
- // TODO: before release, change this back to 2.
- iexportVersionGenerics = iexportVersionPosCol
-
- iexportVersionCurrent = iexportVersionGenerics
+ iexportVersionGo1_11 = 0
+ iexportVersionPosCol = 1
+ iexportVersionGo1_18 = 2
+ iexportVersionGenerics = 2
)
type ident struct {
@@ -123,9 +122,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
version = int64(r.uint64())
switch version {
- case /* iexportVersionGenerics, */ iexportVersionPosCol, iexportVersionGo1_11:
+ case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
default:
- if version > iexportVersionGenerics {
+ if version > iexportVersionGo1_18 {
errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
} else {
errorf("unknown iexport format version %d", version)
@@ -141,9 +140,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
r.Seek(sLen+dLen, io.SeekCurrent)
p := iimporter{
- exportVersion: version,
- ipath: path,
- version: int(version),
+ version: int(version),
+ ipath: path,
stringData: stringData,
stringCache: make(map[uint64]string),
@@ -153,14 +151,15 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
pkgIndex: make(map[*types.Package]map[string]uint64),
typCache: make(map[uint64]types.Type),
// Separate map for typeparams, keyed by their package and unique
- // name (name with subscript).
+ // name.
tparamIndex: make(map[ident]types.Type),
fake: fakeFileSet{
fset: fset,
- files: make(map[string]*token.File),
+ files: make(map[string]*fileInfo),
},
}
+ defer p.fake.setLines() // set lines for files in fset
for i, pt := range predeclared() {
p.typCache[uint64(i)] = pt
@@ -246,9 +245,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
}
type iimporter struct {
- exportVersion int64
- ipath string
- version int
+ version int
+ ipath string
stringData []byte
stringCache map[uint64]string
@@ -261,9 +259,28 @@ type iimporter struct {
fake fakeFileSet
interfaceList []*types.Interface
+
+ indent int // for tracing support
+}
+
+func (p *iimporter) trace(format string, args ...interface{}) {
+ if !trace {
+ // Call sites should also be guarded, but having this check here allows
+ // easily enabling/disabling debug trace statements.
+ return
+ }
+ fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
}
func (p *iimporter) doDecl(pkg *types.Package, name string) {
+ if debug {
+ p.trace("import decl %s", name)
+ p.indent++
+ defer func() {
+ p.indent--
+ p.trace("=> %s", name)
+ }()
+ }
// See if we've already imported this declaration.
if obj := pkg.Scope().Lookup(name); obj != nil {
return
@@ -305,7 +322,7 @@ func (p *iimporter) pkgAt(off uint64) *types.Package {
}
func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
- if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
+ if t, ok := p.typCache[off]; ok && canReuse(base, t) {
return t
}
@@ -317,12 +334,30 @@ func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
r.declReader.Reset(p.declData[off-predeclReserved:])
t := r.doType(base)
- if base == nil || !isInterface(t) {
+ if canReuse(base, t) {
p.typCache[off] = t
}
return t
}
+// canReuse reports whether the type rhs on the RHS of the declaration for def
+// may be re-used.
+//
+// Specifically, if def is non-nil and rhs is an interface type with methods, it
+// may not be re-used because we have a convention of setting the receiver type
+// for interface methods to def.
+func canReuse(def *types.Named, rhs types.Type) bool {
+ if def == nil {
+ return true
+ }
+ iface, _ := rhs.(*types.Interface)
+ if iface == nil {
+ return true
+ }
+ // Don't use iface.Empty() here as iface may not be complete.
+ return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
+}
+
type importReader struct {
p *iimporter
declReader bytes.Reader
@@ -352,8 +387,7 @@ func (r *importReader) obj(name string) {
if tag == 'G' {
tparams = r.tparamList()
}
- sig := r.signature(nil)
- typeparams.SetForSignature(sig, tparams)
+ sig := r.signature(nil, nil, tparams)
r.declare(types.NewFunc(pos, r.currPkg, name, sig))
case 'T', 'U':
@@ -377,23 +411,21 @@ func (r *importReader) obj(name string) {
mpos := r.pos()
mname := r.ident()
recv := r.param()
- msig := r.signature(recv)
// If the receiver has any targs, set those as the
// rparams of the method (since those are the
// typeparams being used in the method sig/body).
- targs := typeparams.NamedTypeArgs(baseType(msig.Recv().Type()))
+ base := baseType(recv.Type())
+ assert(base != nil)
+ targs := typeparams.NamedTypeArgs(base)
+ var rparams []*typeparams.TypeParam
if targs.Len() > 0 {
- rparams := make([]*typeparams.TypeParam, targs.Len())
+ rparams = make([]*typeparams.TypeParam, targs.Len())
for i := range rparams {
- // TODO(rfindley): this is less tolerant than the standard library
- // go/internal/gcimporter, which calls under(...) and is tolerant
- // of nil rparams. Bring them in sync by making the standard
- // library importer stricter.
rparams[i] = targs.At(i).(*typeparams.TypeParam)
}
- typeparams.SetRecvTypeParams(msig, rparams)
}
+ msig := r.signature(recv, rparams, nil)
named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
}
@@ -403,25 +435,30 @@ func (r *importReader) obj(name string) {
// We need to "declare" a typeparam in order to have a name that
// can be referenced recursively (if needed) in the type param's
// bound.
- if r.p.exportVersion < iexportVersionGenerics {
+ if r.p.version < iexportVersionGenerics {
errorf("unexpected type param type")
}
- name0, sub := parseSubscript(name)
+ name0 := tparamName(name)
tn := types.NewTypeName(pos, r.currPkg, name0, nil)
t := typeparams.NewTypeParam(tn, nil)
- if sub == 0 {
- errorf("name %q missing subscript", name)
- }
-
- // TODO(rfindley): can we use a different, stable ID?
- // t.SetId(sub)
// To handle recursive references to the typeparam within its
// bound, save the partial type in tparamIndex before reading the bounds.
id := ident{r.currPkg.Name(), name}
r.p.tparamIndex[id] = t
-
- typeparams.SetTypeParamConstraint(t, r.typ())
+ var implicit bool
+ if r.p.version >= iexportVersionGo1_18 {
+ implicit = r.bool()
+ }
+ constraint := r.typ()
+ if implicit {
+ iface, _ := constraint.(*types.Interface)
+ if iface == nil {
+ errorf("non-interface constraint marked implicit")
+ }
+ typeparams.MarkImplicit(iface)
+ }
+ typeparams.SetTypeParamConstraint(t, constraint)
case 'V':
typ := r.typ()
@@ -439,6 +476,10 @@ func (r *importReader) declare(obj types.Object) {
func (r *importReader) value() (typ types.Type, val constant.Value) {
typ = r.typ()
+ if r.p.version >= iexportVersionGo1_18 {
+ // TODO: add support for using the kind.
+ _ = constant.Kind(r.int64())
+ }
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
case types.IsBoolean:
@@ -581,7 +622,7 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) {
}
func (r *importReader) pos() token.Pos {
- if r.p.exportVersion >= iexportVersionPosCol {
+ if r.p.version >= iexportVersionPosCol {
r.posv1()
} else {
r.posv0()
@@ -629,8 +670,17 @@ func isInterface(t types.Type) bool {
func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
-func (r *importReader) doType(base *types.Named) types.Type {
- switch k := r.kind(); k {
+func (r *importReader) doType(base *types.Named) (res types.Type) {
+ k := r.kind()
+ if debug {
+ r.p.trace("importing type %d (base: %s)", k, base)
+ r.p.indent++
+ defer func() {
+ r.p.indent--
+ r.p.trace("=> %s", res)
+ }()
+ }
+ switch k {
default:
errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
return nil
@@ -653,7 +703,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return types.NewMap(r.typ(), r.typ())
case signatureType:
r.currPkg = r.pkg()
- return r.signature(nil)
+ return r.signature(nil, nil, nil)
case structType:
r.currPkg = r.pkg()
@@ -693,7 +743,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
recv = types.NewVar(token.NoPos, r.currPkg, "", base)
}
- msig := r.signature(recv)
+ msig := r.signature(recv, nil, nil)
methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
}
@@ -702,7 +752,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return typ
case typeParamType:
- if r.p.exportVersion < iexportVersionGenerics {
+ if r.p.version < iexportVersionGenerics {
errorf("unexpected type param type")
}
pkg, name := r.qualifiedIdent()
@@ -716,7 +766,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return r.p.tparamIndex[id]
case instanceType:
- if r.p.exportVersion < iexportVersionGenerics {
+ if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
// pos does not matter for instances: they are positioned on the original
@@ -735,7 +785,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return t
case unionType:
- if r.p.exportVersion < iexportVersionGenerics {
+ if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
terms := make([]*typeparams.Term, r.uint64())
@@ -750,11 +800,11 @@ func (r *importReader) kind() itag {
return itag(r.uint64())
}
-func (r *importReader) signature(recv *types.Var) *types.Signature {
+func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
params := r.paramList()
results := r.paramList()
variadic := params.Len() > 0 && r.bool()
- return types.NewSignature(recv, params, results, variadic)
+ return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
}
func (r *importReader) tparamList() []*typeparams.TypeParam {
@@ -823,23 +873,3 @@ func baseType(typ types.Type) *types.Named {
n, _ := typ.(*types.Named)
return n
}
-
-func parseSubscript(name string) (string, uint64) {
- // Extract the subscript value from the type param name. We export
- // and import the subscript value, so that all type params have
- // unique names.
- sub := uint64(0)
- startsub := -1
- for i, r := range name {
- if '₀' <= r && r < '₀'+10 {
- if startsub == -1 {
- startsub = i
- }
- sub = sub*10 + uint64(r-'₀')
- }
- }
- if startsub >= 0 {
- name = name[:startsub]
- }
- return name, sub
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go
index 817a147e..d892273e 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build !typeparams || !go1.18
-// +build !typeparams !go1.18
+//go:build !go1.18
+// +build !go1.18
package gcimporter
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go
index e6b81fc5..a9938432 100644
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build typeparams && go1.18
-// +build typeparams,go1.18
+//go:build go1.18
+// +build go1.18
package gcimporter
@@ -16,5 +16,8 @@ func additionalPredeclared() []types.Type {
return []types.Type{
// comparable
types.Universe.Lookup("comparable").Type(),
+
+ // any
+ types.Universe.Lookup("any").Type(),
}
}