src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

ureader.go (21149B)


      1 // Copyright 2021 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Derived from go/internal/gcimporter/ureader.go
      6 
      7 package gcimporter
      8 
      9 import (
     10 	"fmt"
     11 	"go/token"
     12 	"go/types"
     13 	"sort"
     14 	"strings"
     15 
     16 	"golang.org/x/tools/internal/aliases"
     17 	"golang.org/x/tools/internal/pkgbits"
     18 	"golang.org/x/tools/internal/typesinternal"
     19 )
     20 
     21 // A pkgReader holds the shared state for reading a unified IR package
     22 // description.
     23 type pkgReader struct {
     24 	pkgbits.PkgDecoder
     25 
     26 	fake fakeFileSet
     27 
     28 	ctxt    *types.Context
     29 	imports map[string]*types.Package // previously imported packages, indexed by path
     30 
     31 	// lazily initialized arrays corresponding to the unified IR
     32 	// PosBase, Pkg, and Type sections, respectively.
     33 	posBases []string // position bases (i.e., file names)
     34 	pkgs     []*types.Package
     35 	typs     []types.Type
     36 
     37 	// laterFns holds functions that need to be invoked at the end of
     38 	// import reading.
     39 	//
     40 	// TODO(mdempsky): Is it safe to have a single "later" slice or do
     41 	// we need to have multiple passes? See comments on CL 386002 and
     42 	// go.dev/issue/52104.
     43 	laterFns []func()
     44 	// laterFors is used in case of 'type A B' to ensure that B is processed before A.
     45 	laterFors map[types.Type]int
     46 
     47 	// ifaces holds a list of constructed Interfaces, which need to have
     48 	// Complete called after importing is done.
     49 	ifaces []*types.Interface
     50 }
     51 
     52 // later adds a function to be invoked at the end of import reading.
     53 func (pr *pkgReader) later(fn func()) {
     54 	pr.laterFns = append(pr.laterFns, fn)
     55 }
     56 
     57 // See cmd/compile/internal/noder.derivedInfo.
     58 type derivedInfo struct {
     59 	idx pkgbits.Index
     60 }
     61 
     62 // See cmd/compile/internal/noder.typeInfo.
     63 type typeInfo struct {
     64 	idx     pkgbits.Index
     65 	derived bool
     66 }
     67 
     68 func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
     69 	if !debug {
     70 		defer func() {
     71 			if x := recover(); x != nil {
     72 				err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x)
     73 			}
     74 		}()
     75 	}
     76 
     77 	s := string(data)
     78 	input := pkgbits.NewPkgDecoder(path, s)
     79 	pkg = readUnifiedPackage(fset, nil, imports, input)
     80 	return
     81 }
     82 
     83 // laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing.
     84 func (pr *pkgReader) laterFor(t types.Type, fn func()) {
     85 	if pr.laterFors == nil {
     86 		pr.laterFors = make(map[types.Type]int)
     87 	}
     88 	pr.laterFors[t] = len(pr.laterFns)
     89 	pr.laterFns = append(pr.laterFns, fn)
     90 }
     91 
     92 // readUnifiedPackage reads a package description from the given
     93 // unified IR export data decoder.
     94 func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
     95 	pr := pkgReader{
     96 		PkgDecoder: input,
     97 
     98 		fake: fakeFileSet{
     99 			fset:  fset,
    100 			files: make(map[string]*fileInfo),
    101 		},
    102 
    103 		ctxt:    ctxt,
    104 		imports: imports,
    105 
    106 		posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
    107 		pkgs:     make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
    108 		typs:     make([]types.Type, input.NumElems(pkgbits.RelocType)),
    109 	}
    110 	defer pr.fake.setLines()
    111 
    112 	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
    113 	pkg := r.pkg()
    114 	if r.Version().Has(pkgbits.HasInit) {
    115 		r.Bool()
    116 	}
    117 
    118 	for i, n := 0, r.Len(); i < n; i++ {
    119 		// As if r.obj(), but avoiding the Scope.Lookup call,
    120 		// to avoid eager loading of imports.
    121 		r.Sync(pkgbits.SyncObject)
    122 		if r.Version().Has(pkgbits.DerivedFuncInstance) {
    123 			assert(!r.Bool())
    124 		}
    125 		r.p.objIdx(r.Reloc(pkgbits.RelocObj))
    126 		assert(r.Len() == 0)
    127 	}
    128 
    129 	r.Sync(pkgbits.SyncEOF)
    130 
    131 	for _, fn := range pr.laterFns {
    132 		fn()
    133 	}
    134 
    135 	for _, iface := range pr.ifaces {
    136 		iface.Complete()
    137 	}
    138 
    139 	// Imports() of pkg are all of the transitive packages that were loaded.
    140 	var imps []*types.Package
    141 	for _, imp := range pr.pkgs {
    142 		if imp != nil && imp != pkg {
    143 			imps = append(imps, imp)
    144 		}
    145 	}
    146 	sort.Sort(byPath(imps))
    147 	pkg.SetImports(imps)
    148 
    149 	pkg.MarkComplete()
    150 	return pkg
    151 }
    152 
    153 // A reader holds the state for reading a single unified IR element
    154 // within a package.
    155 type reader struct {
    156 	pkgbits.Decoder
    157 
    158 	p *pkgReader
    159 
    160 	dict *readerDict
    161 }
    162 
    163 // A readerDict holds the state for type parameters that parameterize
    164 // the current unified IR element.
    165 type readerDict struct {
    166 	rtbounds []typeInfo         // contains constraint types for each parameter in rtparams
    167 	rtparams []*types.TypeParam // contains receiver type parameters for an element
    168 
    169 	tbounds []typeInfo         // contains constraint types for each parameter in tparams
    170 	tparams []*types.TypeParam // contains type parameters for an element
    171 
    172 	// derived is a slice of types derived from tparams, which may be
    173 	// instantiated while reading the current element.
    174 	derived      []derivedInfo
    175 	derivedTypes []types.Type // lazily instantiated from derived
    176 }
    177 
    178 func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
    179 	return &reader{
    180 		Decoder: pr.NewDecoder(k, idx, marker),
    181 		p:       pr,
    182 	}
    183 }
    184 
    185 func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
    186 	return &reader{
    187 		Decoder: pr.TempDecoder(k, idx, marker),
    188 		p:       pr,
    189 	}
    190 }
    191 
    192 func (pr *pkgReader) retireReader(r *reader) {
    193 	pr.RetireDecoder(&r.Decoder)
    194 }
    195 
    196 // @@@ Positions
    197 
    198 func (r *reader) pos() token.Pos {
    199 	r.Sync(pkgbits.SyncPos)
    200 	if !r.Bool() {
    201 		return token.NoPos
    202 	}
    203 
    204 	// TODO(mdempsky): Delta encoding.
    205 	posBase := r.posBase()
    206 	line := r.Uint()
    207 	col := r.Uint()
    208 	return r.p.fake.pos(posBase, int(line), int(col))
    209 }
    210 
    211 func (r *reader) posBase() string {
    212 	return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
    213 }
    214 
    215 func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
    216 	if b := pr.posBases[idx]; b != "" {
    217 		return b
    218 	}
    219 
    220 	var filename string
    221 	{
    222 		r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
    223 
    224 		// Within types2, position bases have a lot more details (e.g.,
    225 		// keeping track of where //line directives appeared exactly).
    226 		//
    227 		// For go/types, we just track the file name.
    228 
    229 		filename = r.String()
    230 
    231 		if r.Bool() { // file base
    232 			// Was: "b = token.NewTrimmedFileBase(filename, true)"
    233 		} else { // line base
    234 			pos := r.pos()
    235 			line := r.Uint()
    236 			col := r.Uint()
    237 
    238 			// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
    239 			_, _, _ = pos, line, col
    240 		}
    241 		pr.retireReader(r)
    242 	}
    243 	b := filename
    244 	pr.posBases[idx] = b
    245 	return b
    246 }
    247 
    248 // @@@ Packages
    249 
    250 func (r *reader) pkg() *types.Package {
    251 	r.Sync(pkgbits.SyncPkg)
    252 	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
    253 }
    254 
    255 func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
    256 	// TODO(mdempsky): Consider using some non-nil pointer to indicate
    257 	// the universe scope, so we don't need to keep re-reading it.
    258 	if pkg := pr.pkgs[idx]; pkg != nil {
    259 		return pkg
    260 	}
    261 
    262 	pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
    263 	pr.pkgs[idx] = pkg
    264 	return pkg
    265 }
    266 
    267 func (r *reader) doPkg() *types.Package {
    268 	path := r.String()
    269 	switch path {
    270 	// cmd/compile emits path="main" for main packages because
    271 	// that's the linker symbol prefix it used; but we need
    272 	// the package's path as it would be reported by go list,
    273 	// hence "main" below.
    274 	// See test at go/packages.TestMainPackagePathInModeTypes.
    275 	case "", "main":
    276 		path = r.p.PkgPath()
    277 	case "builtin":
    278 		return nil // universe
    279 	case "unsafe":
    280 		return types.Unsafe
    281 	}
    282 
    283 	if pkg := r.p.imports[path]; pkg != nil {
    284 		return pkg
    285 	}
    286 
    287 	name := r.String()
    288 
    289 	pkg := types.NewPackage(path, name)
    290 	r.p.imports[path] = pkg
    291 
    292 	return pkg
    293 }
    294 
    295 // @@@ Types
    296 
    297 func (r *reader) typ() types.Type {
    298 	return r.p.typIdx(r.typInfo(), r.dict)
    299 }
    300 
    301 func (r *reader) typInfo() typeInfo {
    302 	r.Sync(pkgbits.SyncType)
    303 	if r.Bool() {
    304 		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
    305 	}
    306 	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
    307 }
    308 
    309 func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
    310 	idx := info.idx
    311 	var where *types.Type
    312 	if info.derived {
    313 		where = &dict.derivedTypes[idx]
    314 		idx = dict.derived[idx].idx
    315 	} else {
    316 		where = &pr.typs[idx]
    317 	}
    318 
    319 	if typ := *where; typ != nil {
    320 		return typ
    321 	}
    322 
    323 	var typ types.Type
    324 	{
    325 		r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
    326 		r.dict = dict
    327 
    328 		typ = r.doTyp()
    329 		assert(typ != nil)
    330 		pr.retireReader(r)
    331 	}
    332 	// See comment in pkgReader.typIdx explaining how this happens.
    333 	if prev := *where; prev != nil {
    334 		return prev
    335 	}
    336 
    337 	*where = typ
    338 	return typ
    339 }
    340 
    341 func (r *reader) doTyp() (res types.Type) {
    342 	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
    343 	default:
    344 		errorf("unhandled type tag: %v", tag)
    345 		panic("unreachable")
    346 
    347 	case pkgbits.TypeBasic:
    348 		return types.Typ[r.Len()]
    349 
    350 	case pkgbits.TypeNamed:
    351 		obj, targs := r.obj()
    352 		name := obj.(*types.TypeName)
    353 		if len(targs) != 0 {
    354 			t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
    355 			return t
    356 		}
    357 		return name.Type()
    358 
    359 	case pkgbits.TypeTypeParam:
    360 		n := r.Len()
    361 		if n < len(r.dict.rtbounds) {
    362 			return r.dict.rtparams[n]
    363 		}
    364 		return r.dict.tparams[n-len(r.dict.rtbounds)]
    365 
    366 	case pkgbits.TypeArray:
    367 		len := int64(r.Uint64())
    368 		return types.NewArray(r.typ(), len)
    369 	case pkgbits.TypeChan:
    370 		dir := types.ChanDir(r.Len())
    371 		return types.NewChan(dir, r.typ())
    372 	case pkgbits.TypeMap:
    373 		return types.NewMap(r.typ(), r.typ())
    374 	case pkgbits.TypePointer:
    375 		return types.NewPointer(r.typ())
    376 	case pkgbits.TypeSignature:
    377 		return r.signature(nil, nil, nil)
    378 	case pkgbits.TypeSlice:
    379 		return types.NewSlice(r.typ())
    380 	case pkgbits.TypeStruct:
    381 		return r.structType()
    382 	case pkgbits.TypeInterface:
    383 		return r.interfaceType()
    384 	case pkgbits.TypeUnion:
    385 		return r.unionType()
    386 	}
    387 }
    388 
    389 func (r *reader) structType() *types.Struct {
    390 	fields := make([]*types.Var, r.Len())
    391 	var tags []string
    392 	for i := range fields {
    393 		pos := r.pos()
    394 		pkg, name := r.selector()
    395 		ftyp := r.typ()
    396 		tag := r.String()
    397 		embedded := r.Bool()
    398 
    399 		fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
    400 		if tag != "" {
    401 			for len(tags) < i {
    402 				tags = append(tags, "")
    403 			}
    404 			tags = append(tags, tag)
    405 		}
    406 	}
    407 	return types.NewStruct(fields, tags)
    408 }
    409 
    410 func (r *reader) unionType() *types.Union {
    411 	terms := make([]*types.Term, r.Len())
    412 	for i := range terms {
    413 		terms[i] = types.NewTerm(r.Bool(), r.typ())
    414 	}
    415 	return types.NewUnion(terms)
    416 }
    417 
    418 func (r *reader) interfaceType() *types.Interface {
    419 	methods := make([]*types.Func, r.Len())
    420 	embeddeds := make([]types.Type, r.Len())
    421 	implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
    422 
    423 	for i := range methods {
    424 		pos := r.pos()
    425 		pkg, name := r.selector()
    426 		mtyp := r.signature(nil, nil, nil)
    427 		methods[i] = types.NewFunc(pos, pkg, name, mtyp)
    428 	}
    429 
    430 	for i := range embeddeds {
    431 		embeddeds[i] = r.typ()
    432 	}
    433 
    434 	iface := types.NewInterfaceType(methods, embeddeds)
    435 	if implicit {
    436 		iface.MarkImplicit()
    437 	}
    438 
    439 	// We need to call iface.Complete(), but if there are any embedded
    440 	// defined types, then we may not have set their underlying
    441 	// interface type yet. So we need to defer calling Complete until
    442 	// after we've called SetUnderlying everywhere.
    443 	//
    444 	// TODO(mdempsky): After CL 424876 lands, it should be safe to call
    445 	// iface.Complete() immediately.
    446 	r.p.ifaces = append(r.p.ifaces, iface)
    447 
    448 	return iface
    449 }
    450 
    451 func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
    452 	r.Sync(pkgbits.SyncSignature)
    453 
    454 	params := r.params()
    455 	results := r.params()
    456 	variadic := r.Bool()
    457 
    458 	return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
    459 }
    460 
    461 func (r *reader) params() *types.Tuple {
    462 	r.Sync(pkgbits.SyncParams)
    463 
    464 	params := make([]*types.Var, r.Len())
    465 	for i := range params {
    466 		params[i] = r.param()
    467 	}
    468 
    469 	return types.NewTuple(params...)
    470 }
    471 
    472 func (r *reader) param() *types.Var {
    473 	r.Sync(pkgbits.SyncParam)
    474 
    475 	pos := r.pos()
    476 	pkg, name := r.localIdent()
    477 	typ := r.typ()
    478 
    479 	return types.NewParam(pos, pkg, name, typ)
    480 }
    481 
    482 // @@@ Objects
    483 
    484 func (r *reader) obj() (types.Object, []types.Type) {
    485 	r.Sync(pkgbits.SyncObject)
    486 
    487 	if r.Version().Has(pkgbits.DerivedFuncInstance) {
    488 		assert(!r.Bool())
    489 	}
    490 
    491 	pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
    492 	obj := pkgScope(pkg).Lookup(name)
    493 
    494 	targs := make([]types.Type, r.Len())
    495 	for i := range targs {
    496 		targs[i] = r.typ()
    497 	}
    498 
    499 	return obj, targs
    500 }
    501 
    502 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
    503 
    504 	var objPkg *types.Package
    505 	var objName string
    506 	var tag pkgbits.CodeObj
    507 	{
    508 		rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
    509 
    510 		objPkg, objName = rname.qualifiedIdent()
    511 		assert(objName != "")
    512 
    513 		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
    514 		pr.retireReader(rname)
    515 	}
    516 
    517 	if tag == pkgbits.ObjStub {
    518 		assert(objPkg == nil || objPkg == types.Unsafe)
    519 		return objPkg, objName
    520 	}
    521 
    522 	// Ignore local types promoted to global scope (#55110).
    523 	if _, suffix := splitVargenSuffix(objName); suffix != "" {
    524 		return objPkg, objName
    525 	}
    526 
    527 	// TODO(mark): This, like the above splitVargenSuffix, is not ideal.
    528 	// Ignore generic methods promoted to global scope.
    529 	if strings.Contains(objName, ".") {
    530 		return objPkg, objName
    531 	}
    532 
    533 	if objPkg.Scope().Lookup(objName) == nil {
    534 		dict := pr.objDictIdx(idx)
    535 
    536 		r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
    537 		r.dict = dict
    538 
    539 		declare := func(obj types.Object) {
    540 			objPkg.Scope().Insert(obj)
    541 		}
    542 
    543 		switch tag {
    544 		default:
    545 			panic("weird")
    546 
    547 		case pkgbits.ObjAlias:
    548 			pos := r.pos()
    549 			var tparams []*types.TypeParam
    550 			if r.Version().Has(pkgbits.AliasTypeParamNames) {
    551 				tparams = r.typeParamNames(false)
    552 			}
    553 			typ := r.typ()
    554 			declare(aliases.New(pos, objPkg, objName, typ, tparams))
    555 
    556 		case pkgbits.ObjConst:
    557 			pos := r.pos()
    558 			typ := r.typ()
    559 			val := r.Value()
    560 			declare(types.NewConst(pos, objPkg, objName, typ, val))
    561 
    562 		case pkgbits.ObjFunc:
    563 			pos := r.pos()
    564 			if r.Version().Has(pkgbits.GenericMethods) {
    565 				assert(!r.Bool()) // generic methods are read in their defining type
    566 			}
    567 			tparams := r.typeParamNames(false)
    568 			sig := r.signature(nil, nil, tparams)
    569 			declare(types.NewFunc(pos, objPkg, objName, sig))
    570 
    571 		case pkgbits.ObjType:
    572 			pos := r.pos()
    573 
    574 			obj := types.NewTypeName(pos, objPkg, objName, nil)
    575 			named := types.NewNamed(obj, nil, nil)
    576 			declare(obj)
    577 
    578 			named.SetTypeParams(r.typeParamNames(false))
    579 
    580 			setUnderlying := func(underlying types.Type) {
    581 				// If the underlying type is an interface, we need to
    582 				// duplicate its methods so we can replace the receiver
    583 				// parameter's type (#49906).
    584 				if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
    585 					methods := make([]*types.Func, iface.NumExplicitMethods())
    586 					for i := range methods {
    587 						fn := iface.ExplicitMethod(i)
    588 						sig := fn.Type().(*types.Signature)
    589 
    590 						recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
    591 						typesinternal.SetVarKind(recv, typesinternal.RecvVar)
    592 						methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic()))
    593 					}
    594 
    595 					embeds := make([]types.Type, iface.NumEmbeddeds())
    596 					for i := range embeds {
    597 						embeds[i] = iface.EmbeddedType(i)
    598 					}
    599 
    600 					newIface := types.NewInterfaceType(methods, embeds)
    601 					r.p.ifaces = append(r.p.ifaces, newIface)
    602 					underlying = newIface
    603 				}
    604 
    605 				named.SetUnderlying(underlying)
    606 			}
    607 
    608 			// Since go.dev/cl/455279, we can assume rhs.Underlying() will
    609 			// always be non-nil. However, to temporarily support users of
    610 			// older snapshot releases, we continue to fallback to the old
    611 			// behavior for now.
    612 			//
    613 			// TODO(mdempsky): Remove fallback code and simplify after
    614 			// allowing time for snapshot users to upgrade.
    615 			rhs := r.typ()
    616 			if underlying := rhs.Underlying(); underlying != nil {
    617 				setUnderlying(underlying)
    618 			} else {
    619 				pk := r.p
    620 				pk.laterFor(named, func() {
    621 					// First be sure that the rhs is initialized, if it needs to be initialized.
    622 					delete(pk.laterFors, named) // prevent cycles
    623 					if i, ok := pk.laterFors[rhs]; ok {
    624 						f := pk.laterFns[i]
    625 						pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op
    626 						f()                        // initialize RHS
    627 					}
    628 					setUnderlying(rhs.Underlying())
    629 				})
    630 			}
    631 
    632 			for i, n := 0, r.Len(); i < n; i++ {
    633 				named.AddMethod(r.method())
    634 			}
    635 
    636 			if r.Version().Has(pkgbits.GenericMethods) {
    637 				for range r.Len() {
    638 					// Careful: objIdx is used to read in package-scoped declarations, which
    639 					// methods are not. Instead, decode it here. This makes it easier to
    640 					// associate it with the type and avoids the main objIdx loop.
    641 					idx := r.Reloc(pkgbits.RelocObj)
    642 
    643 					r := pr.tempReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
    644 					r.dict = pr.objDictIdx(idx)
    645 
    646 					pos := r.pos()
    647 					assert(r.Bool()) // generic method
    648 					pkg, name := r.selector()
    649 					rtparams := r.typeParamNames(true)
    650 					recv := r.param()
    651 					tparams := r.typeParamNames(false)
    652 					sig := r.signature(recv, rtparams, tparams)
    653 
    654 					pr.retireReader(r)
    655 					named.AddMethod(types.NewFunc(pos, pkg, name, sig))
    656 				}
    657 			}
    658 
    659 		case pkgbits.ObjVar:
    660 			pos := r.pos()
    661 			typ := r.typ()
    662 			v := types.NewVar(pos, objPkg, objName, typ)
    663 			typesinternal.SetVarKind(v, typesinternal.PackageVar)
    664 			declare(v)
    665 		}
    666 	}
    667 
    668 	return objPkg, objName
    669 }
    670 
    671 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
    672 
    673 	var dict readerDict
    674 
    675 	{
    676 		r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
    677 		if implicits := r.Len(); implicits != 0 {
    678 			errorf("unexpected object with %v implicit type parameter(s)", implicits)
    679 		}
    680 
    681 		nreceivers := 0
    682 		if r.Version().Has(pkgbits.GenericMethods) {
    683 			nreceivers = r.Len()
    684 		}
    685 		nexplicits := r.Len()
    686 
    687 		dict.rtbounds = make([]typeInfo, nreceivers)
    688 		for i := range dict.rtbounds {
    689 			dict.rtbounds[i] = r.typInfo()
    690 		}
    691 
    692 		dict.tbounds = make([]typeInfo, nexplicits)
    693 		for i := range dict.tbounds {
    694 			dict.tbounds[i] = r.typInfo()
    695 		}
    696 
    697 		dict.derived = make([]derivedInfo, r.Len())
    698 		dict.derivedTypes = make([]types.Type, len(dict.derived))
    699 		for i := range dict.derived {
    700 			dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)}
    701 			if r.Version().Has(pkgbits.DerivedInfoNeeded) {
    702 				assert(!r.Bool())
    703 			}
    704 		}
    705 
    706 		pr.retireReader(r)
    707 	}
    708 	// function references follow, but reader doesn't need those
    709 
    710 	return &dict
    711 }
    712 
    713 func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam {
    714 	r.Sync(pkgbits.SyncTypeParamNames)
    715 
    716 	// Note: This code assumes there are no implicit type parameters.
    717 	// This is fine since it only reads exported declarations, which
    718 	// never have implicits.
    719 
    720 	var in []typeInfo
    721 	var out *[]*types.TypeParam
    722 	if isGenMeth {
    723 		in = r.dict.rtbounds
    724 		out = &r.dict.rtparams
    725 	} else {
    726 		in = r.dict.tbounds
    727 		out = &r.dict.tparams
    728 	}
    729 
    730 	if len(in) == 0 {
    731 		return nil
    732 	}
    733 
    734 	// Careful: Type parameter lists may have cycles. To allow for this,
    735 	// we construct the type parameter list in two passes: first we
    736 	// create all the TypeNames and TypeParams, then we construct and
    737 	// set the bound type.
    738 
    739 	// We have to save tparams outside of the closure, because typeParamNames
    740 	// can be called multiple times with the same dictionary instance.
    741 	tparams := make([]*types.TypeParam, len(in))
    742 	*out = tparams
    743 
    744 	for i := range in {
    745 		pos := r.pos()
    746 		pkg, name := r.localIdent()
    747 
    748 		tname := types.NewTypeName(pos, pkg, name, nil)
    749 		tparams[i] = types.NewTypeParam(tname, nil)
    750 	}
    751 
    752 	// The reader dictionary will continue mutating before we have time
    753 	// to call delayed functions; make a local copy of the constraints.
    754 	types := make([]types.Type, len(in))
    755 	for i, info := range in {
    756 		types[i] = r.p.typIdx(info, r.dict)
    757 	}
    758 
    759 	// This needs to happen later to make sure SetUnderlying has been called.
    760 	r.p.later(func() {
    761 		for i, typ := range types {
    762 			tparams[i].SetConstraint(typ)
    763 		}
    764 	})
    765 
    766 	return tparams
    767 }
    768 
    769 func (r *reader) method() *types.Func {
    770 	r.Sync(pkgbits.SyncMethod)
    771 	pos := r.pos()
    772 	pkg, name := r.selector()
    773 
    774 	rparams := r.typeParamNames(false)
    775 	sig := r.signature(r.param(), rparams, nil)
    776 
    777 	_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
    778 	return types.NewFunc(pos, pkg, name, sig)
    779 }
    780 
    781 func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
    782 func (r *reader) localIdent() (*types.Package, string)     { return r.ident(pkgbits.SyncLocalIdent) }
    783 func (r *reader) selector() (*types.Package, string)       { return r.ident(pkgbits.SyncSelector) }
    784 
    785 func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
    786 	r.Sync(marker)
    787 	return r.pkg(), r.String()
    788 }
    789 
    790 // pkgScope returns pkg.Scope().
    791 // If pkg is nil, it returns types.Universe instead.
    792 //
    793 // TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
    794 func pkgScope(pkg *types.Package) *types.Scope {
    795 	if pkg != nil {
    796 		return pkg.Scope()
    797 	}
    798 	return types.Universe
    799 }
    800 
    801 // See cmd/compile/internal/types.SplitVargenSuffix.
    802 func splitVargenSuffix(name string) (base, suffix string) {
    803 	i := len(name)
    804 	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
    805 		i--
    806 	}
    807 	const dot = "ยท"
    808 	if i >= len(dot) && name[i-len(dot):i] == dot {
    809 		i -= len(dot)
    810 		return name[:i], name[i:]
    811 	}
    812 	return name, ""
    813 }