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

View as plain text