Update dependencies

This commit is contained in:
TwinProduction
2021-10-03 22:15:20 -04:00
parent 2d3fe9795f
commit 154bc7dbc6
1204 changed files with 373532 additions and 50576 deletions

View File

@ -92,16 +92,18 @@ func internalErrorf(format string, args ...interface{}) error {
// BExportData returns binary export data for pkg.
// If no file set is provided, position info will be missing.
func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
defer func() {
if e := recover(); e != nil {
if ierr, ok := e.(internalError); ok {
err = ierr
return
if !debug {
defer func() {
if e := recover(); e != nil {
if ierr, ok := e.(internalError); ok {
err = ierr
return
}
// Not an internal error; panic again.
panic(e)
}
// Not an internal error; panic again.
panic(e)
}
}()
}()
}
p := exporter{
fset: fset,

View File

@ -1029,6 +1029,7 @@ func predeclared() []types.Type {
// used internally by gc; never used by this package or in .a files
anyType{},
}
predecl = append(predecl, additionalPredeclared()...)
})
return predecl
}

View File

@ -19,37 +19,51 @@ import (
"math/big"
"reflect"
"sort"
"golang.org/x/tools/internal/typeparams"
)
// Current indexed export format version. Increase with each format change.
// 0: Go1.11 encoding
const iexportVersion = 0
// Current bundled export format version. Increase with each format change.
// 0: initial implementation
const bundleVersion = 0
// IExportData returns the binary export data for pkg.
// IExportData writes indexed export data for pkg to out.
//
// If no file set is provided, position info will be missing.
// 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(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
defer func() {
if e := recover(); e != nil {
if ierr, ok := e.(internalError); ok {
err = ierr
return
func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
return iexportCommon(out, fset, false, []*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)
}
func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*types.Package) (err error) {
if !debug {
defer func() {
if e := recover(); e != nil {
if ierr, ok := e.(internalError); ok {
err = ierr
return
}
// Not an internal error; panic again.
panic(e)
}
// Not an internal error; panic again.
panic(e)
}
}()
}()
}
p := iexporter{
out: bytes.NewBuffer(nil),
fset: fset,
allPkgs: map[*types.Package]bool{},
stringIndex: map[string]uint64{},
declIndex: map[types.Object]uint64{},
typIndex: map[types.Type]uint64{},
localpkg: pkg,
}
if !bundle {
p.localpkg = pkgs[0]
}
for i, pt := range predeclared() {
@ -60,10 +74,20 @@ func IExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error)
}
// Initialize work queue with exported declarations.
scope := pkg.Scope()
for _, name := range scope.Names() {
if ast.IsExported(name) {
p.pushDecl(scope.Lookup(name))
for _, pkg := range pkgs {
scope := pkg.Scope()
for _, name := range scope.Names() {
if ast.IsExported(name) {
p.pushDecl(scope.Lookup(name))
}
}
if bundle {
// Ensure pkg and its imports are included in the index.
p.allPkgs[pkg] = true
for _, imp := range pkg.Imports() {
p.allPkgs[imp] = true
}
}
}
@ -76,21 +100,35 @@ func IExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error)
dataLen := uint64(p.data0.Len())
w := p.newWriter()
w.writeIndex(p.declIndex)
if bundle {
w.uint64(uint64(len(pkgs)))
for _, pkg := range pkgs {
w.pkg(pkg)
imps := pkg.Imports()
w.uint64(uint64(len(imps)))
for _, imp := range imps {
w.pkg(imp)
}
}
}
w.flush()
// Assemble header.
var hdr intWriter
hdr.WriteByte('i')
if bundle {
hdr.uint64(bundleVersion)
}
hdr.uint64(iexportVersion)
hdr.uint64(uint64(p.strings.Len()))
hdr.uint64(dataLen)
// Flush output.
io.Copy(p.out, &hdr)
io.Copy(p.out, &p.strings)
io.Copy(p.out, &p.data0)
io.Copy(out, &hdr)
io.Copy(out, &p.strings)
io.Copy(out, &p.data0)
return p.out.Bytes(), nil
return nil
}
// writeIndex writes out an object index. mainIndex indicates whether
@ -104,7 +142,9 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
// For the main index, make sure to include every package that
// we reference, even if we're not exporting (or reexporting)
// any symbols from it.
pkgObjs[w.p.localpkg] = nil
if w.p.localpkg != nil {
pkgObjs[w.p.localpkg] = nil
}
for pkg := range w.p.allPkgs {
pkgObjs[pkg] = nil
}
@ -118,7 +158,7 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
pkgs = append(pkgs, pkg)
sort.Slice(objs, func(i, j int) bool {
return objs[i].Name() < objs[j].Name()
return indexName(objs[i]) < indexName(objs[j])
})
}
@ -135,12 +175,26 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
objs := pkgObjs[pkg]
w.uint64(uint64(len(objs)))
for _, obj := range objs {
w.string(obj.Name())
w.string(indexName(obj))
w.uint64(index[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 "" })
}
}
return obj.Name()
}
type iexporter struct {
fset *token.FileSet
out *bytes.Buffer
@ -193,10 +247,11 @@ func (p *iexporter) pushDecl(obj types.Object) {
type exportWriter struct {
p *iexporter
data intWriter
currPkg *types.Package
prevFile string
prevLine int64
data intWriter
currPkg *types.Package
prevFile string
prevLine int64
prevColumn int64
}
func (w *exportWriter) exportPath(pkg *types.Package) string {
@ -221,8 +276,23 @@ func (p *iexporter) doDecl(obj types.Object) {
if sig.Recv() != nil {
panic(internalErrorf("unexpected method: %v", sig))
}
w.tag('F')
// Function.
if typeparams.ForSignature(sig).Len() == 0 {
w.tag('F')
} else {
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.
if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
w.tparamList(tparams, obj.Pkg())
}
w.signature(sig)
case *types.Const:
@ -231,30 +301,46 @@ func (p *iexporter) doDecl(obj types.Object) {
w.value(obj.Type(), obj.Val())
case *types.TypeName:
t := obj.Type()
if tparam, ok := t.(*typeparams.TypeParam); ok {
w.tag('P')
w.pos(obj.Pos())
w.typ(tparam.Constraint(), obj.Pkg())
break
}
if obj.IsAlias() {
w.tag('A')
w.pos(obj.Pos())
w.typ(obj.Type(), obj.Pkg())
w.typ(t, obj.Pkg())
break
}
// Defined type.
w.tag('T')
named, ok := t.(*types.Named)
if !ok {
panic(internalErrorf("%s is not a defined type", t))
}
if typeparams.ForNamed(named).Len() == 0 {
w.tag('T')
} else {
w.tag('U')
}
w.pos(obj.Pos())
if typeparams.ForNamed(named).Len() > 0 {
w.tparamList(typeparams.ForNamed(named), obj.Pkg())
}
underlying := obj.Type().Underlying()
w.typ(underlying, obj.Pkg())
t := obj.Type()
if types.IsInterface(t) {
break
}
named, ok := t.(*types.Named)
if !ok {
panic(internalErrorf("%s is not a defined type", t))
}
n := named.NumMethods()
w.uint64(uint64(n))
for i := 0; i < n; i++ {
@ -278,6 +364,48 @@ func (w *exportWriter) tag(tag byte) {
}
func (w *exportWriter) pos(pos token.Pos) {
if iexportVersion >= iexportVersionPosCol {
w.posV1(pos)
} else {
w.posV0(pos)
}
}
func (w *exportWriter) posV1(pos token.Pos) {
if w.p.fset == nil {
w.int64(0)
return
}
p := w.p.fset.Position(pos)
file := p.Filename
line := int64(p.Line)
column := int64(p.Column)
deltaColumn := (column - w.prevColumn) << 1
deltaLine := (line - w.prevLine) << 1
if file != w.prevFile {
deltaLine |= 1
}
if deltaLine != 0 {
deltaColumn |= 1
}
w.int64(deltaColumn)
if deltaColumn&1 != 0 {
w.int64(deltaLine)
if deltaLine&1 != 0 {
w.string(file)
}
}
w.prevFile = file
w.prevLine = line
w.prevColumn = column
}
func (w *exportWriter) posV0(pos token.Pos) {
if w.p.fset == nil {
w.int64(0)
return
@ -321,8 +449,7 @@ func (w *exportWriter) pkg(pkg *types.Package) {
func (w *exportWriter) qualifiedIdent(obj types.Object) {
// Ensure any referenced declarations are written out too.
w.p.pushDecl(obj)
w.string(obj.Name())
w.string(indexName(obj))
w.pkg(obj.Pkg())
}
@ -358,9 +485,22 @@ func (w *exportWriter) startType(k itag) {
func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
switch t := t.(type) {
case *types.Named:
if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
w.startType(instanceType)
// TODO(rfindley): investigate if this position is correct, and if it
// matters.
w.pos(t.Obj().Pos())
w.typeList(targs, pkg)
w.typ(typeparams.NamedTypeOrigin(t), pkg)
return
}
w.startType(definedType)
w.qualifiedIdent(t.Obj())
case *typeparams.TypeParam:
w.startType(typeParamType)
w.qualifiedIdent(t.Obj())
case *types.Pointer:
w.startType(pointerType)
w.typ(t.Elem(), pkg)
@ -421,9 +561,14 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
n := t.NumEmbeddeds()
w.uint64(uint64(n))
for i := 0; i < n; i++ {
f := t.Embedded(i)
w.pos(f.Obj().Pos())
w.typ(f.Obj().Type(), f.Obj().Pkg())
ft := t.EmbeddedType(i)
tPkg := pkg
if named, _ := ft.(*types.Named); named != nil {
w.pos(named.Obj().Pos())
} else {
w.pos(token.NoPos)
}
w.typ(ft, tPkg)
}
n = t.NumExplicitMethods()
@ -436,6 +581,16 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
w.signature(sig)
}
case *typeparams.Union:
w.startType(unionType)
nt := t.Len()
w.uint64(uint64(nt))
for i := 0; i < nt; i++ {
term := t.Term(i)
w.bool(term.Tilde())
w.typ(term.Type(), pkg)
}
default:
panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
}
@ -457,6 +612,21 @@ func (w *exportWriter) signature(sig *types.Signature) {
}
}
func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
w.uint64(uint64(ts.Len()))
for i := 0; i < ts.Len(); i++ {
w.typ(ts.At(i), pkg)
}
}
func (w *exportWriter) tparamList(list *typeparams.TypeParamList, pkg *types.Package) {
ll := uint64(list.Len())
w.uint64(ll)
for i := 0; i < list.Len(); i++ {
w.typ(list.At(i), pkg)
}
}
func (w *exportWriter) paramList(tup *types.Tuple) {
n := tup.Len()
w.uint64(uint64(n))
@ -474,10 +644,10 @@ func (w *exportWriter) param(obj types.Object) {
func (w *exportWriter) value(typ types.Type, v constant.Value) {
w.typ(typ, nil)
switch v.Kind() {
case constant.Bool:
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
case types.IsBoolean:
w.bool(constant.BoolVal(v))
case constant.Int:
case types.IsInteger:
var i big.Int
if i64, exact := constant.Int64Val(v); exact {
i.SetInt64(i64)
@ -487,25 +657,27 @@ func (w *exportWriter) value(typ types.Type, v constant.Value) {
i.SetString(v.ExactString(), 10)
}
w.mpint(&i, typ)
case constant.Float:
case types.IsFloat:
f := constantToFloat(v)
w.mpfloat(f, typ)
case constant.Complex:
case types.IsComplex:
w.mpfloat(constantToFloat(constant.Real(v)), typ)
w.mpfloat(constantToFloat(constant.Imag(v)), typ)
case constant.String:
case types.IsString:
w.string(constant.StringVal(v))
case constant.Unknown:
// package contains type errors
default:
panic(internalErrorf("unexpected value %v (%T)", v, v))
if b.Kind() == types.Invalid {
// package contains type errors
break
}
panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying()))
}
}
// constantToFloat converts a constant.Value with kind constant.Float to a
// big.Float.
func constantToFloat(x constant.Value) *big.Float {
assert(x.Kind() == constant.Float)
x = constant.ToFloat(x)
// Use the same floating-point precision (512) as cmd/compile
// (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
const mpprec = 512
@ -660,7 +832,7 @@ func (w *exportWriter) localIdent(obj types.Object) {
return
}
name := obj.Name()
name := indexName(obj)
if name == "_" {
w.string("_")
return

View File

@ -18,6 +18,8 @@ import (
"go/types"
"io"
"sort"
"golang.org/x/tools/internal/typeparams"
)
type intReader struct {
@ -41,6 +43,21 @@ func (r *intReader) uint64() uint64 {
return i
}
// 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
)
type ident struct {
pkg string
name string
}
const predeclReserved = 32
type itag uint64
@ -56,32 +73,63 @@ const (
signatureType
structType
interfaceType
typeParamType
instanceType
unionType
)
// IImportData imports a package from the serialized package data
// and returns the number of bytes consumed and a reference to the package.
// and returns 0 and a reference to the package.
// If the export data version is not recognized or the format is otherwise
// compromised, an error is returned.
func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
pkgs, err := iimportCommon(fset, imports, data, false, path)
if err != nil {
return 0, nil, err
}
return 0, pkgs[0], nil
}
// IImportBundle imports a set of packages from the serialized package bundle.
func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
return iimportCommon(fset, imports, data, true, "")
}
func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) {
const currentVersion = 1
version := int64(-1)
defer func() {
if e := recover(); e != nil {
if version > currentVersion {
err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
} else {
err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
if !debug {
defer func() {
if e := recover(); e != nil {
if version > currentVersion {
err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
} else {
err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
}
}
}
}()
}()
}
r := &intReader{bytes.NewReader(data), path}
if bundle {
bundleVersion := r.uint64()
switch bundleVersion {
case bundleVersion:
default:
errorf("unknown bundle format version %d", bundleVersion)
}
}
version = int64(r.uint64())
switch version {
case currentVersion, 0:
case /* iexportVersionGenerics, */ iexportVersionPosCol, iexportVersionGo1_11:
default:
errorf("unknown iexport format version %d", version)
if version > iexportVersionGenerics {
errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
} else {
errorf("unknown iexport format version %d", version)
}
}
sLen := int64(r.uint64())
@ -93,8 +141,9 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
r.Seek(sLen+dLen, io.SeekCurrent)
p := iimporter{
ipath: path,
version: int(version),
exportVersion: version,
ipath: path,
version: int(version),
stringData: stringData,
stringCache: make(map[uint64]string),
@ -103,6 +152,9 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
declData: declData,
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).
tparamIndex: make(map[ident]types.Type),
fake: fakeFileSet{
fset: fset,
@ -143,48 +195,69 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
p.pkgIndex[pkg] = nameIndex
pkgList[i] = pkg
}
if len(pkgList) == 0 {
errorf("no packages found for %s", path)
panic("unreachable")
if bundle {
pkgs = make([]*types.Package, r.uint64())
for i := range pkgs {
pkg := p.pkgAt(r.uint64())
imps := make([]*types.Package, r.uint64())
for j := range imps {
imps[j] = p.pkgAt(r.uint64())
}
pkg.SetImports(imps)
pkgs[i] = pkg
}
} else {
if len(pkgList) == 0 {
errorf("no packages found for %s", path)
panic("unreachable")
}
pkgs = pkgList[:1]
// record all referenced packages as imports
list := append(([]*types.Package)(nil), pkgList[1:]...)
sort.Sort(byPath(list))
pkgs[0].SetImports(list)
}
p.ipkg = pkgList[0]
names := make([]string, 0, len(p.pkgIndex[p.ipkg]))
for name := range p.pkgIndex[p.ipkg] {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
p.doDecl(p.ipkg, name)
for _, pkg := range pkgs {
if pkg.Complete() {
continue
}
names := make([]string, 0, len(p.pkgIndex[pkg]))
for name := range p.pkgIndex[pkg] {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
p.doDecl(pkg, name)
}
// package was imported completely and without errors
pkg.MarkComplete()
}
for _, typ := range p.interfaceList {
typ.Complete()
}
// record all referenced packages as imports
list := append(([]*types.Package)(nil), pkgList[1:]...)
sort.Sort(byPath(list))
p.ipkg.SetImports(list)
// package was imported completely and without errors
p.ipkg.MarkComplete()
consumed, _ := r.Seek(0, io.SeekCurrent)
return int(consumed), p.ipkg, nil
return pkgs, nil
}
type iimporter struct {
ipath string
ipkg *types.Package
version int
exportVersion int64
ipath string
version int
stringData []byte
stringCache map[uint64]string
pkgCache map[uint64]*types.Package
declData []byte
pkgIndex map[*types.Package]map[string]uint64
typCache map[uint64]types.Type
declData []byte
pkgIndex map[*types.Package]map[string]uint64
typCache map[uint64]types.Type
tparamIndex map[ident]types.Type
fake fakeFileSet
interfaceList []*types.Interface
@ -227,9 +300,6 @@ func (p *iimporter) pkgAt(off uint64) *types.Package {
return pkg
}
path := p.stringAt(off)
if path == p.ipath {
return p.ipkg
}
errorf("missing package %q in %q", path, p.ipath)
return nil
}
@ -277,17 +347,27 @@ func (r *importReader) obj(name string) {
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
case 'F':
case 'F', 'G':
var tparams []*typeparams.TypeParam
if tag == 'G' {
tparams = r.tparamList()
}
sig := r.signature(nil)
typeparams.SetForSignature(sig, tparams)
r.declare(types.NewFunc(pos, r.currPkg, name, sig))
case 'T':
case 'T', 'U':
// Types can be recursive. We need to setup a stub
// declaration before recursing.
obj := types.NewTypeName(pos, r.currPkg, name, nil)
named := types.NewNamed(obj, nil, nil)
// Declare obj before calling r.tparamList, so the new type name is recognized
// if used in the constraint of one of its own typeparams (see #48280).
r.declare(obj)
if tag == 'U' {
tparams := r.tparamList()
typeparams.SetForNamed(named, tparams)
}
underlying := r.p.typAt(r.uint64(), named).Underlying()
named.SetUnderlying(underlying)
@ -299,10 +379,50 @@ func (r *importReader) obj(name string) {
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()))
if targs.Len() > 0 {
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)
}
named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
}
}
case 'P':
// 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 {
errorf("unexpected type param type")
}
name0, sub := parseSubscript(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())
case 'V':
typ := r.typ()
@ -435,6 +555,14 @@ func (r *importReader) mpfloat(b *types.Basic) constant.Value {
switch {
case exp > 0:
x = constant.Shift(x, token.SHL, uint(exp))
// Ensure that the imported Kind is Float, else this constant may run into
// bitsize limits on overlarge integers. Eventually we can instead adopt
// the approach of CL 288632, but that CL relies on go/constant APIs that
// were introduced in go1.13.
//
// TODO(rFindley): sync the logic here with tip Go once we no longer
// support go1.12.
x = constant.ToFloat(x)
case exp < 0:
d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
x = constant.BinaryOp(x, token.QUO, d)
@ -453,7 +581,7 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) {
}
func (r *importReader) pos() token.Pos {
if r.p.version >= 1 {
if r.p.exportVersion >= iexportVersionPosCol {
r.posv1()
} else {
r.posv0()
@ -572,6 +700,49 @@ func (r *importReader) doType(base *types.Named) types.Type {
typ := newInterface(methods, embeddeds)
r.p.interfaceList = append(r.p.interfaceList, typ)
return typ
case typeParamType:
if r.p.exportVersion < iexportVersionGenerics {
errorf("unexpected type param type")
}
pkg, name := r.qualifiedIdent()
id := ident{pkg.Name(), name}
if t, ok := r.p.tparamIndex[id]; ok {
// We're already in the process of importing this typeparam.
return t
}
// Otherwise, import the definition of the typeparam now.
r.p.doDecl(pkg, name)
return r.p.tparamIndex[id]
case instanceType:
if r.p.exportVersion < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
// pos does not matter for instances: they are positioned on the original
// type.
_ = r.pos()
len := r.uint64()
targs := make([]types.Type, len)
for i := range targs {
targs[i] = r.typ()
}
baseType := r.typ()
// The imported instantiated type doesn't include any methods, so
// we must always use the methods of the base (orig) type.
// TODO provide a non-nil *Environment
t, _ := typeparams.Instantiate(nil, baseType, targs, false)
return t
case unionType:
if r.p.exportVersion < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
terms := make([]*typeparams.Term, r.uint64())
for i := range terms {
terms[i] = typeparams.NewTerm(r.bool(), r.typ())
}
return typeparams.NewUnion(terms)
}
}
@ -586,6 +757,20 @@ func (r *importReader) signature(recv *types.Var) *types.Signature {
return types.NewSignature(recv, params, results, variadic)
}
func (r *importReader) tparamList() []*typeparams.TypeParam {
n := r.uint64()
if n == 0 {
return nil
}
xs := make([]*typeparams.TypeParam, n)
for i := range xs {
// Note: the standard library importer is tolerant of nil types here,
// though would panic in SetTypeParams.
xs[i] = r.typ().(*typeparams.TypeParam)
}
return xs
}
func (r *importReader) paramList() *types.Tuple {
xs := make([]*types.Var, r.uint64())
for i := range xs {
@ -628,3 +813,33 @@ func (r *importReader) byte() byte {
}
return x
}
func baseType(typ types.Type) *types.Named {
// pointer receivers are never types.Named types
if p, _ := typ.(*types.Pointer); p != nil {
typ = p.Elem()
}
// receiver base types are always (possibly generic) types.Named types
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
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.11
// +build !go1.11
package gcimporter

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.11
// +build go1.11
package gcimporter

View File

@ -0,0 +1,16 @@
// 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 !typeparams || !go1.18
// +build !typeparams !go1.18
package gcimporter
import "go/types"
const iexportVersion = iexportVersionGo1_11
func additionalPredeclared() []types.Type {
return nil
}

View File

@ -0,0 +1,20 @@
// 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 typeparams && go1.18
// +build typeparams,go1.18
package gcimporter
import "go/types"
const iexportVersion = iexportVersionGenerics
// additionalPredeclared returns additional predeclared types in go.1.18.
func additionalPredeclared() []types.Type {
return []types.Type{
// comparable
types.Universe.Lookup("comparable").Type(),
}
}

View File

@ -22,7 +22,7 @@ func GetSizesGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string
if rawErr != nil {
if strings.Contains(rawErr.Error(), "cannot find main module") {
if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
// TODO(matloob): Is this a problem in practice?
inv.Verb = "env"