...

Source file src/golang.org/x/tools/internal/gcimporter/ureader_yes.go

Documentation: golang.org/x/tools/internal/gcimporter

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

View as plain text