Source file src/cmd/compile/internal/testimporter/ureader.go

     1  // Copyright 2026 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 testimporter
     6  
     7  import (
     8  	"cmp"
     9  	"slices"
    10  
    11  	"cmd/compile/internal/base"
    12  	"cmd/compile/internal/syntax"
    13  	"cmd/compile/internal/types2"
    14  	"cmd/internal/src"
    15  	"internal/pkgbits"
    16  )
    17  
    18  type pkgReader struct {
    19  	pkgbits.PkgDecoder
    20  
    21  	ctxt        *types2.Context
    22  	imports     map[string]*types2.Package
    23  	enableAlias bool // whether to use aliases
    24  
    25  	posBases []*syntax.PosBase
    26  	pkgs     []*types2.Package
    27  	typs     []types2.Type
    28  }
    29  
    30  func ReadPackage(ctxt *types2.Context, imports map[string]*types2.Package, input pkgbits.PkgDecoder) *types2.Package {
    31  	pr := pkgReader{
    32  		PkgDecoder: input,
    33  
    34  		ctxt:        ctxt,
    35  		imports:     imports,
    36  		enableAlias: true,
    37  
    38  		posBases: make([]*syntax.PosBase, input.NumElems(pkgbits.SectionPosBase)),
    39  		pkgs:     make([]*types2.Package, input.NumElems(pkgbits.SectionPkg)),
    40  		typs:     make([]types2.Type, input.NumElems(pkgbits.SectionType)),
    41  	}
    42  
    43  	r := pr.newReader(pkgbits.SectionMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
    44  	pkg := r.pkg()
    45  
    46  	if r.Version().Has(pkgbits.HasInit) {
    47  		r.Bool()
    48  	}
    49  
    50  	for i, n := 0, r.Len(); i < n; i++ {
    51  		// As if r.obj(), but avoiding the Scope.Lookup call,
    52  		// to avoid eager loading of imports.
    53  		r.Sync(pkgbits.SyncObject)
    54  		if r.Version().Has(pkgbits.DerivedFuncInstance) {
    55  			assert(!r.Bool())
    56  		}
    57  		r.p.objIdx(r.Reloc(pkgbits.SectionObj))
    58  		assert(r.Len() == 0)
    59  	}
    60  
    61  	r.Sync(pkgbits.SyncEOF)
    62  
    63  	pkg.MarkComplete()
    64  	return pkg
    65  }
    66  
    67  type reader struct {
    68  	pkgbits.Decoder
    69  
    70  	p *pkgReader
    71  
    72  	dict    *readerDict
    73  	delayed []func()
    74  }
    75  
    76  type readerDict struct {
    77  	rtbounds []typeInfo
    78  	rtparams []*types2.TypeParam
    79  
    80  	tbounds []typeInfo
    81  	tparams []*types2.TypeParam
    82  
    83  	derived      []derivedInfo
    84  	derivedTypes []types2.Type
    85  }
    86  
    87  type readerTypeBound struct {
    88  	derived  bool
    89  	boundIdx int
    90  }
    91  
    92  func (pr *pkgReader) newReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
    93  	return &reader{
    94  		Decoder: pr.NewDecoder(k, idx, marker),
    95  		p:       pr,
    96  	}
    97  }
    98  
    99  func (pr *pkgReader) tempReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
   100  	return &reader{
   101  		Decoder: pr.TempDecoder(k, idx, marker),
   102  		p:       pr,
   103  	}
   104  }
   105  
   106  func (pr *pkgReader) retireReader(r *reader) {
   107  	pr.RetireDecoder(&r.Decoder)
   108  }
   109  
   110  // @@@ Positions
   111  
   112  func (r *reader) pos() syntax.Pos {
   113  	r.Sync(pkgbits.SyncPos)
   114  	if !r.Bool() {
   115  		return syntax.Pos{}
   116  	}
   117  
   118  	// TODO(mdempsky): Delta encoding.
   119  	posBase := r.posBase()
   120  	line := r.Uint()
   121  	col := r.Uint()
   122  	return syntax.MakePos(posBase, line, col)
   123  }
   124  
   125  func (r *reader) posBase() *syntax.PosBase {
   126  	return r.p.posBaseIdx(r.Reloc(pkgbits.SectionPosBase))
   127  }
   128  
   129  func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *syntax.PosBase {
   130  	if b := pr.posBases[idx]; b != nil {
   131  		return b
   132  	}
   133  	var b *syntax.PosBase
   134  	{
   135  		r := pr.tempReader(pkgbits.SectionPosBase, idx, pkgbits.SyncPosBase)
   136  
   137  		filename := r.String()
   138  
   139  		if r.Bool() {
   140  			b = syntax.NewTrimmedFileBase(filename, true)
   141  		} else {
   142  			pos := r.pos()
   143  			line := r.Uint()
   144  			col := r.Uint()
   145  			b = syntax.NewLineBase(pos, filename, true, line, col)
   146  		}
   147  		pr.retireReader(r)
   148  	}
   149  
   150  	pr.posBases[idx] = b
   151  	return b
   152  }
   153  
   154  // @@@ Packages
   155  
   156  func (r *reader) pkg() *types2.Package {
   157  	r.Sync(pkgbits.SyncPkg)
   158  	return r.p.pkgIdx(r.Reloc(pkgbits.SectionPkg))
   159  }
   160  
   161  func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types2.Package {
   162  	// TODO(mdempsky): Consider using some non-nil pointer to indicate
   163  	// the universe scope, so we don't need to keep re-reading it.
   164  	if pkg := pr.pkgs[idx]; pkg != nil {
   165  		return pkg
   166  	}
   167  
   168  	pkg := pr.newReader(pkgbits.SectionPkg, idx, pkgbits.SyncPkgDef).doPkg()
   169  	pr.pkgs[idx] = pkg
   170  	return pkg
   171  }
   172  
   173  func (r *reader) doPkg() *types2.Package {
   174  	path := r.String()
   175  	switch path {
   176  	case "":
   177  		path = r.p.PkgPath()
   178  	case "builtin":
   179  		return nil // universe
   180  	case "unsafe":
   181  		return types2.Unsafe
   182  	}
   183  
   184  	if pkg := r.p.imports[path]; pkg != nil {
   185  		return pkg
   186  	}
   187  
   188  	name := r.String()
   189  	pkg := types2.NewPackage(path, name)
   190  	r.p.imports[path] = pkg
   191  
   192  	// TODO(mdempsky): The list of imported packages is important for
   193  	// go/types, but we could probably skip populating it for types2.
   194  	imports := make([]*types2.Package, r.Len())
   195  	for i := range imports {
   196  		imports[i] = r.pkg()
   197  	}
   198  	pkg.SetImports(imports)
   199  
   200  	return pkg
   201  }
   202  
   203  // @@@ Types
   204  
   205  func (r *reader) typ() types2.Type {
   206  	return r.p.typIdx(r.typInfo(), r.dict)
   207  }
   208  
   209  func (r *reader) typInfo() typeInfo {
   210  	r.Sync(pkgbits.SyncType)
   211  	if r.Bool() {
   212  		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
   213  	}
   214  	return typeInfo{idx: r.Reloc(pkgbits.SectionType), derived: false}
   215  }
   216  
   217  func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types2.Type {
   218  	idx := info.idx
   219  	var where *types2.Type
   220  	if info.derived {
   221  		where = &dict.derivedTypes[idx]
   222  		idx = dict.derived[idx].idx
   223  	} else {
   224  		where = &pr.typs[idx]
   225  	}
   226  
   227  	if typ := *where; typ != nil {
   228  		return typ
   229  	}
   230  
   231  	var typ types2.Type
   232  	{
   233  		r := pr.tempReader(pkgbits.SectionType, idx, pkgbits.SyncTypeIdx)
   234  		r.dict = dict
   235  
   236  		typ = r.doTyp()
   237  		assert(typ != nil)
   238  		pr.retireReader(r)
   239  	}
   240  
   241  	// See comment in pkgReader.typIdx explaining how this happens.
   242  	if prev := *where; prev != nil {
   243  		return prev
   244  	}
   245  
   246  	*where = typ
   247  	return typ
   248  }
   249  
   250  func (r *reader) doTyp() (res types2.Type) {
   251  	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
   252  	default:
   253  		base.FatalfAt(src.NoXPos, "unhandled type tag: %v", tag)
   254  		panic("unreachable")
   255  
   256  	case pkgbits.TypeBasic:
   257  		return types2.Typ[r.Len()]
   258  
   259  	case pkgbits.TypeNamed:
   260  		obj, targs := r.obj()
   261  		name := obj.(*types2.TypeName)
   262  		if len(targs) != 0 {
   263  			t, _ := types2.Instantiate(r.p.ctxt, name.Type(), targs, false)
   264  			return t
   265  		}
   266  		return name.Type()
   267  
   268  	case pkgbits.TypeTypeParam:
   269  		n := r.Len()
   270  		if n < len(r.dict.rtbounds) {
   271  			return r.dict.rtparams[n]
   272  		}
   273  		return r.dict.tparams[n-len(r.dict.rtbounds)]
   274  
   275  	case pkgbits.TypeArray:
   276  		len := int64(r.Uint64())
   277  		return types2.NewArray(r.typ(), len)
   278  	case pkgbits.TypeChan:
   279  		dir := types2.ChanDir(r.Len())
   280  		return types2.NewChan(dir, r.typ())
   281  	case pkgbits.TypeMap:
   282  		return types2.NewMap(r.typ(), r.typ())
   283  	case pkgbits.TypePointer:
   284  		return types2.NewPointer(r.typ())
   285  	case pkgbits.TypeSignature:
   286  		return r.signature(nil, nil, nil)
   287  	case pkgbits.TypeSlice:
   288  		return types2.NewSlice(r.typ())
   289  	case pkgbits.TypeStruct:
   290  		return r.structType()
   291  	case pkgbits.TypeInterface:
   292  		return r.interfaceType()
   293  	case pkgbits.TypeUnion:
   294  		return r.unionType()
   295  	}
   296  }
   297  
   298  func (r *reader) structType() *types2.Struct {
   299  	fields := make([]*types2.Var, r.Len())
   300  	var tags []string
   301  	for i := range fields {
   302  		pos := r.pos()
   303  		pkg, name := r.selector()
   304  		ftyp := r.typ()
   305  		tag := r.String()
   306  		embedded := r.Bool()
   307  
   308  		fields[i] = types2.NewField(pos, pkg, name, ftyp, embedded)
   309  		if tag != "" {
   310  			for len(tags) < i {
   311  				tags = append(tags, "")
   312  			}
   313  			tags = append(tags, tag)
   314  		}
   315  	}
   316  	return types2.NewStruct(fields, tags)
   317  }
   318  
   319  func (r *reader) unionType() *types2.Union {
   320  	terms := make([]*types2.Term, r.Len())
   321  	for i := range terms {
   322  		terms[i] = types2.NewTerm(r.Bool(), r.typ())
   323  	}
   324  	return types2.NewUnion(terms)
   325  }
   326  
   327  func (r *reader) interfaceType() *types2.Interface {
   328  	methods := make([]*types2.Func, r.Len())
   329  	embeddeds := make([]types2.Type, r.Len())
   330  	implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
   331  
   332  	for i := range methods {
   333  		pos := r.pos()
   334  		pkg, name := r.selector()
   335  		mtyp := r.signature(nil, nil, nil)
   336  		methods[i] = types2.NewFunc(pos, pkg, name, mtyp)
   337  	}
   338  
   339  	for i := range embeddeds {
   340  		embeddeds[i] = r.typ()
   341  	}
   342  
   343  	iface := types2.NewInterfaceType(methods, embeddeds)
   344  	if implicit {
   345  		iface.MarkImplicit()
   346  	}
   347  	return iface
   348  }
   349  
   350  func (r *reader) signature(recv *types2.Var, rtparams, tparams []*types2.TypeParam) *types2.Signature {
   351  	r.Sync(pkgbits.SyncSignature)
   352  
   353  	params := r.params()
   354  	results := r.params()
   355  	variadic := r.Bool()
   356  
   357  	return types2.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
   358  }
   359  
   360  func (r *reader) params() *types2.Tuple {
   361  	r.Sync(pkgbits.SyncParams)
   362  	params := make([]*types2.Var, r.Len())
   363  	for i := range params {
   364  		params[i] = r.param()
   365  	}
   366  	return types2.NewTuple(params...)
   367  }
   368  
   369  func (r *reader) param() *types2.Var {
   370  	r.Sync(pkgbits.SyncParam)
   371  
   372  	pos := r.pos()
   373  	pkg, name := r.localIdent()
   374  	typ := r.typ()
   375  
   376  	return types2.NewParam(pos, pkg, name, typ)
   377  }
   378  
   379  // @@@ Objects
   380  
   381  func (r *reader) obj() (types2.Object, []types2.Type) {
   382  	r.Sync(pkgbits.SyncObject)
   383  
   384  	if r.Version().Has(pkgbits.DerivedFuncInstance) {
   385  		assert(!r.Bool())
   386  	}
   387  
   388  	pkg, name := r.p.objIdx(r.Reloc(pkgbits.SectionObj))
   389  	obj := pkg.Scope().Lookup(name)
   390  
   391  	targs := make([]types2.Type, r.Len())
   392  	for i := range targs {
   393  		targs[i] = r.typ()
   394  	}
   395  
   396  	return obj, targs
   397  }
   398  
   399  func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
   400  	var objPkg *types2.Package
   401  	var objName string
   402  	var tag pkgbits.CodeObj
   403  	{
   404  		rname := pr.tempReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
   405  
   406  		objPkg, objName = rname.qualifiedIdent()
   407  		assert(objName != "")
   408  
   409  		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
   410  		pr.retireReader(rname)
   411  	}
   412  
   413  	if tag == pkgbits.ObjStub {
   414  		base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg)
   415  		return objPkg, objName
   416  	}
   417  
   418  	objPkg.Scope().InsertLazy(objName, func() types2.Object {
   419  		dict := pr.objDictIdx(idx)
   420  
   421  		r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
   422  		r.dict = dict
   423  
   424  		switch tag {
   425  		default:
   426  			panic("weird")
   427  
   428  		case pkgbits.ObjAlias:
   429  			pos := r.pos()
   430  			var tparams []*types2.TypeParam
   431  			if r.Version().Has(pkgbits.AliasTypeParamNames) {
   432  				tparams = r.typeParamNames(false, false)
   433  			}
   434  			typ := r.typ()
   435  			return newAliasTypeName(pr.enableAlias, pos, objPkg, objName, typ, tparams)
   436  
   437  		case pkgbits.ObjConst:
   438  			pos := r.pos()
   439  			typ := r.typ()
   440  			val := r.Value()
   441  			return types2.NewConst(pos, objPkg, objName, typ, val)
   442  
   443  		case pkgbits.ObjFunc:
   444  			pos := r.pos()
   445  			if r.Version().Has(pkgbits.GenericMethods) {
   446  				assert(!r.Bool()) // generic methods are read in their defining type
   447  			}
   448  			tparams := r.typeParamNames(false, false)
   449  			sig := r.signature(nil, nil, tparams)
   450  			return types2.NewFunc(pos, objPkg, objName, sig)
   451  
   452  		case pkgbits.ObjType:
   453  			pos := r.pos()
   454  
   455  			return types2.NewTypeNameLazy(pos, objPkg, objName, func(_ *types2.Named) ([]*types2.TypeParam, types2.Type, []*types2.Func, []func()) {
   456  				tparams := r.typeParamNames(true, false)
   457  
   458  				// TODO(mdempsky): Rewrite receiver types to underlying is an
   459  				// Interface? The go/types importer does this (I think because
   460  				// unit tests expected that), but cmd/compile doesn't care
   461  				// about it, so maybe we can avoid worrying about that here.
   462  				underlying := r.typ().Underlying()
   463  
   464  				type indexedMethod struct {
   465  					index int // (or -1 in V4)
   466  					fn    *types2.Func
   467  				}
   468  				var methods []indexedMethod
   469  
   470  				if r.Version().Has(pkgbits.GenericMethods) {
   471  					// V4 (go1.27.0) emitted all non-generic methods
   472  					// before all generic ones, discarding source
   473  					// order: a bug (go.dev/issue/81188).
   474  					// V5 (go1.27.x) fixes it by emitting an explicit
   475  					// index along with each method.
   476  
   477  					// ordinary methods
   478  					for range r.Len() {
   479  						idx, m := r.method(true)
   480  						methods = append(methods, indexedMethod{idx, m})
   481  					}
   482  
   483  					// generic methods
   484  					for range r.Len() {
   485  						// Careful: objIdx is used to read in package-scoped declarations, which
   486  						// methods are not. Instead, decode it here. This makes it easier to
   487  						// associate it with the type and avoids the main objIdx loop.
   488  						idx := r.Reloc(pkgbits.SectionObj)
   489  
   490  						t := pr.tempReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
   491  						t.dict = pr.objDictIdx(idx)
   492  
   493  						pos := t.pos()
   494  						assert(t.Bool()) // generic method
   495  						pkg, name := t.selector()
   496  						rtparams := t.typeParamNames(true, true)
   497  						recv := t.param()
   498  						methodIdx := -1
   499  						if r.Version().Has(pkgbits.PreserveMethodOrder) {
   500  							methodIdx = t.Len()
   501  						}
   502  						tparams := t.typeParamNames(true, false)
   503  						sig := t.signature(recv, rtparams, tparams)
   504  
   505  						r.delayed = append(r.delayed, t.delayed...) // propagate before retiring
   506  						pr.retireReader(t)
   507  						methods = append(methods, indexedMethod{methodIdx, types2.NewFunc(pos, pkg, name, sig)})
   508  					}
   509  
   510  					if r.Version().Has(pkgbits.PreserveMethodOrder) {
   511  						slices.SortFunc(methods, func(a, b indexedMethod) int {
   512  							return cmp.Compare(a.index, b.index)
   513  						})
   514  					}
   515  				} else {
   516  					for range r.Len() {
   517  						_, m := r.method(true)
   518  						methods = append(methods, indexedMethod{-1, m})
   519  					}
   520  				}
   521  
   522  				funcs := make([]*types2.Func, len(methods))
   523  				for i, m := range methods {
   524  					funcs[i] = m.fn
   525  				}
   526  
   527  				return tparams, underlying, funcs, r.delayed
   528  			})
   529  
   530  		case pkgbits.ObjVar:
   531  			pos := r.pos()
   532  			typ := r.typ()
   533  			return types2.NewVar(pos, objPkg, objName, typ)
   534  		}
   535  	})
   536  
   537  	return objPkg, objName
   538  }
   539  
   540  func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
   541  	var dict readerDict
   542  	{
   543  		r := pr.tempReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
   544  
   545  		if implicits := r.Len(); implicits != 0 {
   546  			base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
   547  		}
   548  
   549  		nreceivers := 0
   550  		if r.Version().Has(pkgbits.GenericMethods) {
   551  			nreceivers = r.Len()
   552  		}
   553  		nexplicits := r.Len()
   554  
   555  		dict.rtbounds = make([]typeInfo, nreceivers)
   556  		for i := range dict.rtbounds {
   557  			dict.rtbounds[i] = r.typInfo()
   558  		}
   559  
   560  		dict.tbounds = make([]typeInfo, nexplicits)
   561  		for i := range dict.tbounds {
   562  			dict.tbounds[i] = r.typInfo()
   563  		}
   564  
   565  		dict.derived = make([]derivedInfo, r.Len())
   566  		dict.derivedTypes = make([]types2.Type, len(dict.derived))
   567  		for i := range dict.derived {
   568  			dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
   569  			if r.Version().Has(pkgbits.DerivedInfoNeeded) {
   570  				assert(!r.Bool())
   571  			}
   572  		}
   573  
   574  		pr.retireReader(r)
   575  	}
   576  	// function references follow, but reader doesn't need those
   577  
   578  	return &dict
   579  }
   580  
   581  func (r *reader) typeParamNames(isLazy bool, isGenMeth bool) []*types2.TypeParam {
   582  	r.Sync(pkgbits.SyncTypeParamNames)
   583  
   584  	// Note: This code assumes there are no implicit type parameters.
   585  	// This is fine since it only reads exported declarations, which
   586  	// never have implicits.
   587  
   588  	var in []typeInfo
   589  	var out *[]*types2.TypeParam
   590  	if isGenMeth {
   591  		in = r.dict.rtbounds
   592  		out = &r.dict.rtparams
   593  	} else {
   594  		in = r.dict.tbounds
   595  		out = &r.dict.tparams
   596  	}
   597  
   598  	if len(in) == 0 {
   599  		return nil
   600  	}
   601  
   602  	// Careful: Type parameter lists may have cycles. To allow for this,
   603  	// we construct the type parameter list in two passes: first we
   604  	// create all the TypeNames and TypeParams, then we construct and
   605  	// set the bound type.
   606  
   607  	// We have to save tparams outside of the closure, because typeParamNames
   608  	// can be called multiple times with the same dictionary instance.
   609  	tparams := make([]*types2.TypeParam, len(in))
   610  	*out = tparams
   611  
   612  	for i := range in {
   613  		pos := r.pos()
   614  		pkg, name := r.localIdent()
   615  
   616  		tname := types2.NewTypeName(pos, pkg, name, nil)
   617  		tparams[i] = types2.NewTypeParam(tname, nil)
   618  	}
   619  
   620  	// Type parameters that are read by lazy loaders cannot have their
   621  	// constraints set eagerly; do them after loading (go.dev/issue/63285).
   622  	if isLazy {
   623  		// The reader dictionary will continue mutating before we have time
   624  		// to call delayed functions; make a local copy of the constraints.
   625  		types := make([]types2.Type, len(in))
   626  		for i, info := range in {
   627  			types[i] = r.p.typIdx(info, r.dict)
   628  		}
   629  
   630  		r.delayed = append(r.delayed, func() {
   631  			for i, typ := range types {
   632  				tparams[i].SetConstraint(typ)
   633  			}
   634  		})
   635  	} else {
   636  		for i, info := range in {
   637  			tparams[i].SetConstraint(r.p.typIdx(info, r.dict))
   638  		}
   639  	}
   640  
   641  	return tparams
   642  }
   643  
   644  func (r *reader) method(isLazy bool) (int, *types2.Func) {
   645  	r.Sync(pkgbits.SyncMethod)
   646  	idx := -1
   647  	if r.Version().Has(pkgbits.PreserveMethodOrder) {
   648  		idx = r.Len()
   649  	}
   650  	pos := r.pos()
   651  	pkg, name := r.selector()
   652  
   653  	rtparams := r.typeParamNames(isLazy, false)
   654  	sig := r.signature(r.param(), rtparams, nil)
   655  
   656  	_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
   657  	return idx, types2.NewFunc(pos, pkg, name, sig)
   658  }
   659  
   660  func (r *reader) qualifiedIdent() (*types2.Package, string) { return r.ident(pkgbits.SyncSym) }
   661  func (r *reader) localIdent() (*types2.Package, string)     { return r.ident(pkgbits.SyncLocalIdent) }
   662  func (r *reader) selector() (*types2.Package, string)       { return r.ident(pkgbits.SyncSelector) }
   663  
   664  func (r *reader) ident(marker pkgbits.SyncMarker) (*types2.Package, string) {
   665  	r.Sync(marker)
   666  	return r.pkg(), r.String()
   667  }
   668  
   669  // newAliasTypeName returns a new TypeName, with a materialized *types2.Alias if supported.
   670  func newAliasTypeName(aliases bool, pos syntax.Pos, pkg *types2.Package, name string, rhs types2.Type, tparams []*types2.TypeParam) *types2.TypeName {
   671  	// Copied from x/tools/internal/aliases.NewAlias via
   672  	// GOROOT/src/go/internal/gcimporter/ureader.go.
   673  	if aliases {
   674  		tname := types2.NewTypeName(pos, pkg, name, nil)
   675  		a := types2.NewAlias(tname, rhs) // form TypeName -> Alias cycle
   676  		a.SetTypeParams(tparams)
   677  		return tname
   678  	}
   679  	assert(len(tparams) == 0)
   680  	return types2.NewTypeName(pos, pkg, name, rhs)
   681  }
   682  

View as plain text