ureader_yes.go raw

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