Source file src/go/internal/gcimporter/ureader.go

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

View as plain text