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

View as plain text