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

View as plain text