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
5package noder
6
7import (
8	"encoding/hex"
9	"fmt"
10	"go/constant"
11	"internal/buildcfg"
12	"internal/pkgbits"
13	"path/filepath"
14	"strings"
15
16	"cmd/compile/internal/base"
17	"cmd/compile/internal/dwarfgen"
18	"cmd/compile/internal/inline"
19	"cmd/compile/internal/inline/interleaved"
20	"cmd/compile/internal/ir"
21	"cmd/compile/internal/objw"
22	"cmd/compile/internal/reflectdata"
23	"cmd/compile/internal/staticinit"
24	"cmd/compile/internal/typecheck"
25	"cmd/compile/internal/types"
26	"cmd/internal/notsha256"
27	"cmd/internal/obj"
28	"cmd/internal/objabi"
29	"cmd/internal/src"
30)
31
32// This file implements cmd/compile backend's reader for the Unified
33// IR export data.
34
35// A pkgReader reads Unified IR export data.
36type pkgReader struct {
37	pkgbits.PkgDecoder
38
39	// Indices for encoded things; lazily populated as needed.
40	//
41	// Note: Objects (i.e., ir.Names) are lazily instantiated by
42	// populating their types.Sym.Def; see objReader below.
43
44	posBases []*src.PosBase
45	pkgs     []*types.Pkg
46	typs     []*types.Type
47
48	// offset for rewriting the given (absolute!) index into the output,
49	// but bitwise inverted so we can detect if we're missing the entry
50	// or not.
51	newindex []pkgbits.Index
52}
53
54func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader {
55	return &pkgReader{
56		PkgDecoder: pr,
57
58		posBases: make([]*src.PosBase, pr.NumElems(pkgbits.RelocPosBase)),
59		pkgs:     make([]*types.Pkg, pr.NumElems(pkgbits.RelocPkg)),
60		typs:     make([]*types.Type, pr.NumElems(pkgbits.RelocType)),
61
62		newindex: make([]pkgbits.Index, pr.TotalElems()),
63	}
64}
65
66// A pkgReaderIndex compactly identifies an index (and its
67// corresponding dictionary) within a package's export data.
68type pkgReaderIndex struct {
69	pr        *pkgReader
70	idx       pkgbits.Index
71	dict      *readerDict
72	methodSym *types.Sym
73
74	synthetic func(pos src.XPos, r *reader)
75}
76
77func (pri pkgReaderIndex) asReader(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *reader {
78	if pri.synthetic != nil {
79		return &reader{synthetic: pri.synthetic}
80	}
81
82	r := pri.pr.newReader(k, pri.idx, marker)
83	r.dict = pri.dict
84	r.methodSym = pri.methodSym
85	return r
86}
87
88func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
89	return &reader{
90		Decoder: pr.NewDecoder(k, idx, marker),
91		p:       pr,
92	}
93}
94
95// A reader provides APIs for reading an individual element.
96type reader struct {
97	pkgbits.Decoder
98
99	p *pkgReader
100
101	dict *readerDict
102
103	// TODO(mdempsky): The state below is all specific to reading
104	// function bodies. It probably makes sense to split it out
105	// separately so that it doesn't take up space in every reader
106	// instance.
107
108	curfn       *ir.Func
109	locals      []*ir.Name
110	closureVars []*ir.Name
111
112	// funarghack is used during inlining to suppress setting
113	// Field.Nname to the inlined copies of the parameters. This is
114	// necessary because we reuse the same types.Type as the original
115	// function, and most of the compiler still relies on field.Nname to
116	// find parameters/results.
117	funarghack bool
118
119	// methodSym is the name of method's name, if reading a method.
120	// It's nil if reading a normal function or closure body.
121	methodSym *types.Sym
122
123	// dictParam is the .dict param, if any.
124	dictParam *ir.Name
125
126	// synthetic is a callback function to construct a synthetic
127	// function body. It's used for creating the bodies of function
128	// literals used to curry arguments to shaped functions.
129	synthetic func(pos src.XPos, r *reader)
130
131	// scopeVars is a stack tracking the number of variables declared in
132	// the current function at the moment each open scope was opened.
133	scopeVars         []int
134	marker            dwarfgen.ScopeMarker
135	lastCloseScopePos src.XPos
136
137	// === details for handling inline body expansion ===
138
139	// If we're reading in a function body because of inlining, this is
140	// the call that we're inlining for.
141	inlCaller    *ir.Func
142	inlCall      *ir.CallExpr
143	inlFunc      *ir.Func
144	inlTreeIndex int
145	inlPosBases  map[*src.PosBase]*src.PosBase
146
147	// suppressInlPos tracks whether position base rewriting for
148	// inlining should be suppressed. See funcLit.
149	suppressInlPos int
150
151	delayResults bool
152
153	// Label to return to.
154	retlabel *types.Sym
155}
156
157// A readerDict represents an instantiated "compile-time dictionary,"
158// used for resolving any derived types needed for instantiating a
159// generic object.
160//
161// A compile-time dictionary can either be "shaped" or "non-shaped."
162// Shaped compile-time dictionaries are only used for instantiating
163// shaped type definitions and function bodies, while non-shaped
164// compile-time dictionaries are used for instantiating runtime
165// dictionaries.
166type readerDict struct {
167	shaped bool // whether this is a shaped dictionary
168
169	// baseSym is the symbol for the object this dictionary belongs to.
170	// If the object is an instantiated function or defined type, then
171	// baseSym is the mangled symbol, including any type arguments.
172	baseSym *types.Sym
173
174	// For non-shaped dictionaries, shapedObj is a reference to the
175	// corresponding shaped object (always a function or defined type).
176	shapedObj *ir.Name
177
178	// targs holds the implicit and explicit type arguments in use for
179	// reading the current object. For example:
180	//
181	//	func F[T any]() {
182	//		type X[U any] struct { t T; u U }
183	//		var _ X[string]
184	//	}
185	//
186	//	var _ = F[int]
187	//
188	// While instantiating F[int], we need to in turn instantiate
189	// X[string]. [int] and [string] are explicit type arguments for F
190	// and X, respectively; but [int] is also the implicit type
191	// arguments for X.
192	//
193	// (As an analogy to function literals, explicits are the function
194	// literal's formal parameters, while implicits are variables
195	// captured by the function literal.)
196	targs []*types.Type
197
198	// implicits counts how many of types within targs are implicit type
199	// arguments; the rest are explicit.
200	implicits int
201
202	derived      []derivedInfo // reloc index of the derived type's descriptor
203	derivedTypes []*types.Type // slice of previously computed derived types
204
205	// These slices correspond to entries in the runtime dictionary.
206	typeParamMethodExprs []readerMethodExprInfo
207	subdicts             []objInfo
208	rtypes               []typeInfo
209	itabs                []itabInfo
210}
211
212type readerMethodExprInfo struct {
213	typeParamIdx int
214	method       *types.Sym
215}
216
217func setType(n ir.Node, typ *types.Type) {
218	n.SetType(typ)
219	n.SetTypecheck(1)
220}
221
222func setValue(name *ir.Name, val constant.Value) {
223	name.SetVal(val)
224	name.Defn = nil
225}
226
227// @@@ Positions
228
229// pos reads a position from the bitstream.
230func (r *reader) pos() src.XPos {
231	return base.Ctxt.PosTable.XPos(r.pos0())
232}
233
234// origPos reads a position from the bitstream, and returns both the
235// original raw position and an inlining-adjusted position.
236func (r *reader) origPos() (origPos, inlPos src.XPos) {
237	r.suppressInlPos++
238	origPos = r.pos()
239	r.suppressInlPos--
240	inlPos = r.inlPos(origPos)
241	return
242}
243
244func (r *reader) pos0() src.Pos {
245	r.Sync(pkgbits.SyncPos)
246	if !r.Bool() {
247		return src.NoPos
248	}
249
250	posBase := r.posBase()
251	line := r.Uint()
252	col := r.Uint()
253	return src.MakePos(posBase, line, col)
254}
255
256// posBase reads a position base from the bitstream.
257func (r *reader) posBase() *src.PosBase {
258	return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)))
259}
260
261// posBaseIdx returns the specified position base, reading it first if
262// needed.
263func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *src.PosBase {
264	if b := pr.posBases[idx]; b != nil {
265		return b
266	}
267
268	r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
269	var b *src.PosBase
270
271	absFilename := r.String()
272	filename := absFilename
273
274	// For build artifact stability, the export data format only
275	// contains the "absolute" filename as returned by objabi.AbsFile.
276	// However, some tests (e.g., test/run.go's asmcheck tests) expect
277	// to see the full, original filename printed out. Re-expanding
278	// "$GOROOT" to buildcfg.GOROOT is a close-enough approximation to
279	// satisfy this.
280	//
281	// The export data format only ever uses slash paths
282	// (for cross-operating-system reproducible builds),
283	// but error messages need to use native paths (backslash on Windows)
284	// as if they had been specified on the command line.
285	// (The go command always passes native paths to the compiler.)
286	const dollarGOROOT = "$GOROOT"
287	if buildcfg.GOROOT != "" && strings.HasPrefix(filename, dollarGOROOT) {
288		filename = filepath.FromSlash(buildcfg.GOROOT + filename[len(dollarGOROOT):])
289	}
290
291	if r.Bool() {
292		b = src.NewFileBase(filename, absFilename)
293	} else {
294		pos := r.pos0()
295		line := r.Uint()
296		col := r.Uint()
297		b = src.NewLinePragmaBase(pos, filename, absFilename, line, col)
298	}
299
300	pr.posBases[idx] = b
301	return b
302}
303
304// inlPosBase returns the inlining-adjusted src.PosBase corresponding
305// to oldBase, which must be a non-inlined position. When not
306// inlining, this is just oldBase.
307func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase {
308	if index := oldBase.InliningIndex(); index >= 0 {
309		base.Fatalf("oldBase %v already has inlining index %v", oldBase, index)
310	}
311
312	if r.inlCall == nil || r.suppressInlPos != 0 {
313		return oldBase
314	}
315
316	if newBase, ok := r.inlPosBases[oldBase]; ok {
317		return newBase
318	}
319
320	newBase := src.NewInliningBase(oldBase, r.inlTreeIndex)
321	r.inlPosBases[oldBase] = newBase
322	return newBase
323}
324
325// inlPos returns the inlining-adjusted src.XPos corresponding to
326// xpos, which must be a non-inlined position. When not inlining, this
327// is just xpos.
328func (r *reader) inlPos(xpos src.XPos) src.XPos {
329	pos := base.Ctxt.PosTable.Pos(xpos)
330	pos.SetBase(r.inlPosBase(pos.Base()))
331	return base.Ctxt.PosTable.XPos(pos)
332}
333
334// @@@ Packages
335
336// pkg reads a package reference from the bitstream.
337func (r *reader) pkg() *types.Pkg {
338	r.Sync(pkgbits.SyncPkg)
339	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
340}
341
342// pkgIdx returns the specified package from the export data, reading
343// it first if needed.
344func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Pkg {
345	if pkg := pr.pkgs[idx]; pkg != nil {
346		return pkg
347	}
348
349	pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
350	pr.pkgs[idx] = pkg
351	return pkg
352}
353
354// doPkg reads a package definition from the bitstream.
355func (r *reader) doPkg() *types.Pkg {
356	path := r.String()
357	switch path {
358	case "":
359		path = r.p.PkgPath()
360	case "builtin":
361		return types.BuiltinPkg
362	case "unsafe":
363		return types.UnsafePkg
364	}
365
366	name := r.String()
367
368	pkg := types.NewPkg(path, "")
369
370	if pkg.Name == "" {
371		pkg.Name = name
372	} else {
373		base.Assertf(pkg.Name == name, "package %q has name %q, but want %q", pkg.Path, pkg.Name, name)
374	}
375
376	return pkg
377}
378
379// @@@ Types
380
381func (r *reader) typ() *types.Type {
382	return r.typWrapped(true)
383}
384
385// typWrapped is like typ, but allows suppressing generation of
386// unnecessary wrappers as a compile-time optimization.
387func (r *reader) typWrapped(wrapped bool) *types.Type {
388	return r.p.typIdx(r.typInfo(), r.dict, wrapped)
389}
390
391func (r *reader) typInfo() typeInfo {
392	r.Sync(pkgbits.SyncType)
393	if r.Bool() {
394		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
395	}
396	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
397}
398
399// typListIdx returns a list of the specified types, resolving derived
400// types within the given dictionary.
401func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type {
402	typs := make([]*types.Type, len(infos))
403	for i, info := range infos {
404		typs[i] = pr.typIdx(info, dict, true)
405	}
406	return typs
407}
408
409// typIdx returns the specified type. If info specifies a derived
410// type, it's resolved within the given dictionary. If wrapped is
411// true, then method wrappers will be generated, if appropriate.
412func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type {
413	idx := info.idx
414	var where **types.Type
415	if info.derived {
416		where = &dict.derivedTypes[idx]
417		idx = dict.derived[idx].idx
418	} else {
419		where = &pr.typs[idx]
420	}
421
422	if typ := *where; typ != nil {
423		return typ
424	}
425
426	r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
427	r.dict = dict
428
429	typ := r.doTyp()
430	if typ == nil {
431		base.Fatalf("doTyp returned nil for info=%v", info)
432	}
433
434	// For recursive type declarations involving interfaces and aliases,
435	// above r.doTyp() call may have already set pr.typs[idx], so just
436	// double check and return the type.
437	//
438	// Example:
439	//
440	//     type F = func(I)
441	//
442	//     type I interface {
443	//         m(F)
444	//     }
445	//
446	// The writer writes data types in following index order:
447	//
448	//     0: func(I)
449	//     1: I
450	//     2: interface{m(func(I))}
451	//
452	// The reader resolves it in following index order:
453	//
454	//     0 -> 1 -> 2 -> 0 -> 1
455	//
456	// and can divide in logically 2 steps:
457	//
458	//  - 0 -> 1     : first time the reader reach type I,
459	//                 it creates new named type with symbol I.
460	//
461	//  - 2 -> 0 -> 1: the reader ends up reaching symbol I again,
462	//                 now the symbol I was setup in above step, so
463	//                 the reader just return the named type.
464	//
465	// Now, the functions called return, the pr.typs looks like below:
466	//
467	//  - 0 -> 1 -> 2 -> 0 : [<T> I <T>]
468	//  - 0 -> 1 -> 2      : [func(I) I <T>]
469	//  - 0 -> 1           : [func(I) I interface { "".m(func("".I)) }]
470	//
471	// The idx 1, corresponding with type I was resolved successfully
472	// after r.doTyp() call.
473
474	if prev := *where; prev != nil {
475		return prev
476	}
477
478	if wrapped {
479		// Only cache if we're adding wrappers, so that other callers that
480		// find a cached type know it was wrapped.
481		*where = typ
482
483		r.needWrapper(typ)
484	}
485
486	if !typ.IsUntyped() {
487		types.CheckSize(typ)
488	}
489
490	return typ
491}
492
493func (r *reader) doTyp() *types.Type {
494	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
495	default:
496		panic(fmt.Sprintf("unexpected type: %v", tag))
497
498	case pkgbits.TypeBasic:
499		return *basics[r.Len()]
500
501	case pkgbits.TypeNamed:
502		obj := r.obj()
503		assert(obj.Op() == ir.OTYPE)
504		return obj.Type()
505
506	case pkgbits.TypeTypeParam:
507		return r.dict.targs[r.Len()]
508
509	case pkgbits.TypeArray:
510		len := int64(r.Uint64())
511		return types.NewArray(r.typ(), len)
512	case pkgbits.TypeChan:
513		dir := dirs[r.Len()]
514		return types.NewChan(r.typ(), dir)
515	case pkgbits.TypeMap:
516		return types.NewMap(r.typ(), r.typ())
517	case pkgbits.TypePointer:
518		return types.NewPtr(r.typ())
519	case pkgbits.TypeSignature:
520		return r.signature(nil)
521	case pkgbits.TypeSlice:
522		return types.NewSlice(r.typ())
523	case pkgbits.TypeStruct:
524		return r.structType()
525	case pkgbits.TypeInterface:
526		return r.interfaceType()
527	case pkgbits.TypeUnion:
528		return r.unionType()
529	}
530}
531
532func (r *reader) unionType() *types.Type {
533	// In the types1 universe, we only need to handle value types.
534	// Impure interfaces (i.e., interfaces with non-trivial type sets
535	// like "int | string") can only appear as type parameter bounds,
536	// and this is enforced by the types2 type checker.
537	//
538	// However, type unions can still appear in pure interfaces if the
539	// type union is equivalent to "any". E.g., typeparam/issue52124.go
540	// declares variables with the type "interface { any | int }".
541	//
542	// To avoid needing to represent type unions in types1 (since we
543	// don't have any uses for that today anyway), we simply fold them
544	// to "any".
545
546	// TODO(mdempsky): Restore consistency check to make sure folding to
547	// "any" is safe. This is unfortunately tricky, because a pure
548	// interface can reference impure interfaces too, including
549	// cyclically (#60117).
550	if false {
551		pure := false
552		for i, n := 0, r.Len(); i < n; i++ {
553			_ = r.Bool() // tilde
554			term := r.typ()
555			if term.IsEmptyInterface() {
556				pure = true
557			}
558		}
559		if !pure {
560			base.Fatalf("impure type set used in value type")
561		}
562	}
563
564	return types.Types[types.TINTER]
565}
566
567func (r *reader) interfaceType() *types.Type {
568	nmethods, nembeddeds := r.Len(), r.Len()
569	implicit := nmethods == 0 && nembeddeds == 1 && r.Bool()
570	assert(!implicit) // implicit interfaces only appear in constraints
571
572	fields := make([]*types.Field, nmethods+nembeddeds)
573	methods, embeddeds := fields[:nmethods], fields[nmethods:]
574
575	for i := range methods {
576		methods[i] = types.NewField(r.pos(), r.selector(), r.signature(types.FakeRecv()))
577	}
578	for i := range embeddeds {
579		embeddeds[i] = types.NewField(src.NoXPos, nil, r.typ())
580	}
581
582	if len(fields) == 0 {
583		return types.Types[types.TINTER] // empty interface
584	}
585	return types.NewInterface(fields)
586}
587
588func (r *reader) structType() *types.Type {
589	fields := make([]*types.Field, r.Len())
590	for i := range fields {
591		field := types.NewField(r.pos(), r.selector(), r.typ())
592		field.Note = r.String()
593		if r.Bool() {
594			field.Embedded = 1
595		}
596		fields[i] = field
597	}
598	return types.NewStruct(fields)
599}
600
601func (r *reader) signature(recv *types.Field) *types.Type {
602	r.Sync(pkgbits.SyncSignature)
603
604	params := r.params()
605	results := r.params()
606	if r.Bool() { // variadic
607		params[len(params)-1].SetIsDDD(true)
608	}
609
610	return types.NewSignature(recv, params, results)
611}
612
613func (r *reader) params() []*types.Field {
614	r.Sync(pkgbits.SyncParams)
615	params := make([]*types.Field, r.Len())
616	for i := range params {
617		params[i] = r.param()
618	}
619	return params
620}
621
622func (r *reader) param() *types.Field {
623	r.Sync(pkgbits.SyncParam)
624	return types.NewField(r.pos(), r.localIdent(), r.typ())
625}
626
627// @@@ Objects
628
629// objReader maps qualified identifiers (represented as *types.Sym) to
630// a pkgReader and corresponding index that can be used for reading
631// that object's definition.
632var objReader = map[*types.Sym]pkgReaderIndex{}
633
634// obj reads an instantiated object reference from the bitstream.
635func (r *reader) obj() ir.Node {
636	return r.p.objInstIdx(r.objInfo(), r.dict, false)
637}
638
639// objInfo reads an instantiated object reference from the bitstream
640// and returns the encoded reference to it, without instantiating it.
641func (r *reader) objInfo() objInfo {
642	r.Sync(pkgbits.SyncObject)
643	assert(!r.Bool()) // TODO(mdempsky): Remove; was derived func inst.
644	idx := r.Reloc(pkgbits.RelocObj)
645
646	explicits := make([]typeInfo, r.Len())
647	for i := range explicits {
648		explicits[i] = r.typInfo()
649	}
650
651	return objInfo{idx, explicits}
652}
653
654// objInstIdx returns the encoded, instantiated object. If shaped is
655// true, then the shaped variant of the object is returned instead.
656func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node {
657	explicits := pr.typListIdx(info.explicits, dict)
658
659	var implicits []*types.Type
660	if dict != nil {
661		implicits = dict.targs
662	}
663
664	return pr.objIdx(info.idx, implicits, explicits, shaped)
665}
666
667// objIdx returns the specified object, instantiated with the given
668// type arguments, if any.
669// If shaped is true, then the shaped variant of the object is returned
670// instead.
671func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) ir.Node {
672	n, err := pr.objIdxMayFail(idx, implicits, explicits, shaped)
673	if err != nil {
674		base.Fatalf("%v", err)
675	}
676	return n
677}
678
679// objIdxMayFail is equivalent to objIdx, but returns an error rather than
680// failing the build if this object requires type arguments and the incorrect
681// number of type arguments were passed.
682//
683// Other sources of internal failure (such as duplicate definitions) still fail
684// the build.
685func (pr *pkgReader) objIdxMayFail(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) (ir.Node, error) {
686	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
687	_, sym := rname.qualifiedIdent()
688	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
689
690	if tag == pkgbits.ObjStub {
691		assert(!sym.IsBlank())
692		switch sym.Pkg {
693		case types.BuiltinPkg, types.UnsafePkg:
694			return sym.Def.(ir.Node), nil
695		}
696		if pri, ok := objReader[sym]; ok {
697			return pri.pr.objIdxMayFail(pri.idx, nil, explicits, shaped)
698		}
699		if sym.Pkg.Path == "runtime" {
700			return typecheck.LookupRuntime(sym.Name), nil
701		}
702		base.Fatalf("unresolved stub: %v", sym)
703	}
704
705	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, shaped)
706	if err != nil {
707		return nil, err
708	}
709
710	sym = dict.baseSym
711	if !sym.IsBlank() && sym.Def != nil {
712		return sym.Def.(*ir.Name), nil
713	}
714
715	r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
716	rext := pr.newReader(pkgbits.RelocObjExt, idx, pkgbits.SyncObject1)
717
718	r.dict = dict
719	rext.dict = dict
720
721	do := func(op ir.Op, hasTParams bool) *ir.Name {
722		pos := r.pos()
723		setBasePos(pos)
724		if hasTParams {
725			r.typeParamNames()
726		}
727
728		name := ir.NewDeclNameAt(pos, op, sym)
729		name.Class = ir.PEXTERN // may be overridden later
730		if !sym.IsBlank() {
731			if sym.Def != nil {
732				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
733			}
734			assert(sym.Def == nil)
735			sym.Def = name
736		}
737		return name
738	}
739
740	switch tag {
741	default:
742		panic("unexpected object")
743
744	case pkgbits.ObjAlias:
745		name := do(ir.OTYPE, false)
746
747		// Clumsy dance: the r.typ() call here might recursively find this
748		// type alias name, before we've set its type (#66873). So we
749		// temporarily clear sym.Def and then restore it later, if still
750		// unset.
751		hack := sym.Def == name
752		if hack {
753			sym.Def = nil
754		}
755		typ := r.typ()
756		if hack {
757			if sym.Def != nil {
758				name = sym.Def.(*ir.Name)
759				assert(name.Type() == typ)
760				return name, nil
761			}
762			sym.Def = name
763		}
764
765		setType(name, typ)
766		name.SetAlias(true)
767		return name, nil
768
769	case pkgbits.ObjConst:
770		name := do(ir.OLITERAL, false)
771		typ := r.typ()
772		val := FixValue(typ, r.Value())
773		setType(name, typ)
774		setValue(name, val)
775		return name, nil
776
777	case pkgbits.ObjFunc:
778		if sym.Name == "init" {
779			sym = Renameinit()
780		}
781
782		npos := r.pos()
783		setBasePos(npos)
784		r.typeParamNames()
785		typ := r.signature(nil)
786		fpos := r.pos()
787
788		fn := ir.NewFunc(fpos, npos, sym, typ)
789		name := fn.Nname
790		if !sym.IsBlank() {
791			if sym.Def != nil {
792				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
793			}
794			assert(sym.Def == nil)
795			sym.Def = name
796		}
797
798		if r.hasTypeParams() {
799			name.Func.SetDupok(true)
800			if r.dict.shaped {
801				setType(name, shapeSig(name.Func, r.dict))
802			} else {
803				todoDicts = append(todoDicts, func() {
804					r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
805				})
806			}
807		}
808
809		rext.funcExt(name, nil)
810		return name, nil
811
812	case pkgbits.ObjType:
813		name := do(ir.OTYPE, true)
814		typ := types.NewNamed(name)
815		setType(name, typ)
816		if r.hasTypeParams() && r.dict.shaped {
817			typ.SetHasShape(true)
818		}
819
820		// Important: We need to do this before SetUnderlying.
821		rext.typeExt(name)
822
823		// We need to defer CheckSize until we've called SetUnderlying to
824		// handle recursive types.
825		types.DeferCheckSize()
826		typ.SetUnderlying(r.typWrapped(false))
827		types.ResumeCheckSize()
828
829		if r.hasTypeParams() && !r.dict.shaped {
830			todoDicts = append(todoDicts, func() {
831				r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
832			})
833		}
834
835		methods := make([]*types.Field, r.Len())
836		for i := range methods {
837			methods[i] = r.method(rext)
838		}
839		if len(methods) != 0 {
840			typ.SetMethods(methods)
841		}
842
843		if !r.dict.shaped {
844			r.needWrapper(typ)
845		}
846
847		return name, nil
848
849	case pkgbits.ObjVar:
850		name := do(ir.ONAME, false)
851		setType(name, r.typ())
852		rext.varExt(name)
853		return name, nil
854	}
855}
856
857func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
858	if !dict.hasTypeParams() {
859		return sym
860	}
861
862	// If sym is a locally defined generic type, we need the suffix to
863	// stay at the end after mangling so that types/fmt.go can strip it
864	// out again when writing the type's runtime descriptor (#54456).
865	base, suffix := types.SplitVargenSuffix(sym.Name)
866
867	var buf strings.Builder
868	buf.WriteString(base)
869	buf.WriteByte('[')
870	for i, targ := range dict.targs {
871		if i > 0 {
872			if i == dict.implicits {
873				buf.WriteByte(';')
874			} else {
875				buf.WriteByte(',')
876			}
877		}
878		buf.WriteString(targ.LinkString())
879	}
880	buf.WriteByte(']')
881	buf.WriteString(suffix)
882	return sym.Pkg.Lookup(buf.String())
883}
884
885// shapify returns the shape type for targ.
886//
887// If basic is true, then the type argument is used to instantiate a
888// type parameter whose constraint is a basic interface.
889func shapify(targ *types.Type, basic bool) *types.Type {
890	if targ.Kind() == types.TFORW {
891		if targ.IsFullyInstantiated() {
892			// For recursive instantiated type argument, it may  still be a TFORW
893			// when shapifying happens. If we don't have targ's underlying type,
894			// shapify won't work. The worst case is we end up not reusing code
895			// optimally in some tricky cases.
896			if base.Debug.Shapify != 0 {
897				base.Warn("skipping shaping of recursive type %v", targ)
898			}
899			if targ.HasShape() {
900				return targ
901			}
902		} else {
903			base.Fatalf("%v is missing its underlying type", targ)
904		}
905	}
906	// For fully instantiated shape interface type, use it as-is. Otherwise, the instantiation
907	// involved recursive generic interface may cause mismatching in function signature, see issue #65362.
908	if targ.Kind() == types.TINTER && targ.IsFullyInstantiated() && targ.HasShape() {
909		return targ
910	}
911
912	// When a pointer type is used to instantiate a type parameter
913	// constrained by a basic interface, we know the pointer's element
914	// type can't matter to the generated code. In this case, we can use
915	// an arbitrary pointer type as the shape type. (To match the
916	// non-unified frontend, we use `*byte`.)
917	//
918	// Otherwise, we simply use the type's underlying type as its shape.
919	//
920	// TODO(mdempsky): It should be possible to do much more aggressive
921	// shaping still; e.g., collapsing all pointer-shaped types into a
922	// common type, collapsing scalars of the same size/alignment into a
923	// common type, recursively shaping the element types of composite
924	// types, and discarding struct field names and tags. However, we'll
925	// need to start tracking how type parameters are actually used to
926	// implement some of these optimizations.
927	under := targ.Underlying()
928	if basic && targ.IsPtr() && !targ.Elem().NotInHeap() {
929		under = types.NewPtr(types.Types[types.TUINT8])
930	}
931
932	// Hash long type names to bound symbol name length seen by users,
933	// particularly for large protobuf structs (#65030).
934	uls := under.LinkString()
935	if base.Debug.MaxShapeLen != 0 &&
936		len(uls) > base.Debug.MaxShapeLen {
937		h := notsha256.Sum256([]byte(uls))
938		uls = hex.EncodeToString(h[:])
939	}
940
941	sym := types.ShapePkg.Lookup(uls)
942	if sym.Def == nil {
943		name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
944		typ := types.NewNamed(name)
945		typ.SetUnderlying(under)
946		sym.Def = typed(typ, name)
947	}
948	res := sym.Def.Type()
949	assert(res.IsShape())
950	assert(res.HasShape())
951	return res
952}
953
954// objDictIdx reads and returns the specified object dictionary.
955func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) (*readerDict, error) {
956	r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
957
958	dict := readerDict{
959		shaped: shaped,
960	}
961
962	nimplicits := r.Len()
963	nexplicits := r.Len()
964
965	if nimplicits > len(implicits) || nexplicits != len(explicits) {
966		return nil, fmt.Errorf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits))
967	}
968
969	dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
970	dict.implicits = nimplicits
971
972	// Within the compiler, we can just skip over the type parameters.
973	for range dict.targs[dict.implicits:] {
974		// Skip past bounds without actually evaluating them.
975		r.typInfo()
976	}
977
978	dict.derived = make([]derivedInfo, r.Len())
979	dict.derivedTypes = make([]*types.Type, len(dict.derived))
980	for i := range dict.derived {
981		dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
982	}
983
984	// Runtime dictionary information; private to the compiler.
985
986	// If any type argument is already shaped, then we're constructing a
987	// shaped object, even if not explicitly requested (i.e., calling
988	// objIdx with shaped==true). This can happen with instantiating
989	// types that are referenced within a function body.
990	for _, targ := range dict.targs {
991		if targ.HasShape() {
992			dict.shaped = true
993			break
994		}
995	}
996
997	// And if we're constructing a shaped object, then shapify all type
998	// arguments.
999	for i, targ := range dict.targs {
1000		basic := r.Bool()
1001		if dict.shaped {
1002			dict.targs[i] = shapify(targ, basic)
1003		}
1004	}
1005
1006	dict.baseSym = dict.mangle(sym)
1007
1008	dict.typeParamMethodExprs = make([]readerMethodExprInfo, r.Len())
1009	for i := range dict.typeParamMethodExprs {
1010		typeParamIdx := r.Len()
1011		method := r.selector()
1012
1013		dict.typeParamMethodExprs[i] = readerMethodExprInfo{typeParamIdx, method}
1014	}
1015
1016	dict.subdicts = make([]objInfo, r.Len())
1017	for i := range dict.subdicts {
1018		dict.subdicts[i] = r.objInfo()
1019	}
1020
1021	dict.rtypes = make([]typeInfo, r.Len())
1022	for i := range dict.rtypes {
1023		dict.rtypes[i] = r.typInfo()
1024	}
1025
1026	dict.itabs = make([]itabInfo, r.Len())
1027	for i := range dict.itabs {
1028		dict.itabs[i] = itabInfo{typ: r.typInfo(), iface: r.typInfo()}
1029	}
1030
1031	return &dict, nil
1032}
1033
1034func (r *reader) typeParamNames() {
1035	r.Sync(pkgbits.SyncTypeParamNames)
1036
1037	for range r.dict.targs[r.dict.implicits:] {
1038		r.pos()
1039		r.localIdent()
1040	}
1041}
1042
1043func (r *reader) method(rext *reader) *types.Field {
1044	r.Sync(pkgbits.SyncMethod)
1045	npos := r.pos()
1046	sym := r.selector()
1047	r.typeParamNames()
1048	recv := r.param()
1049	typ := r.signature(recv)
1050
1051	fpos := r.pos()
1052	fn := ir.NewFunc(fpos, npos, ir.MethodSym(recv.Type, sym), typ)
1053	name := fn.Nname
1054
1055	if r.hasTypeParams() {
1056		name.Func.SetDupok(true)
1057		if r.dict.shaped {
1058			typ = shapeSig(name.Func, r.dict)
1059			setType(name, typ)
1060		}
1061	}
1062
1063	rext.funcExt(name, sym)
1064
1065	meth := types.NewField(name.Func.Pos(), sym, typ)
1066	meth.Nname = name
1067	meth.SetNointerface(name.Func.Pragma&ir.Nointerface != 0)
1068
1069	return meth
1070}
1071
1072func (r *reader) qualifiedIdent() (pkg *types.Pkg, sym *types.Sym) {
1073	r.Sync(pkgbits.SyncSym)
1074	pkg = r.pkg()
1075	if name := r.String(); name != "" {
1076		sym = pkg.Lookup(name)
1077	}
1078	return
1079}
1080
1081func (r *reader) localIdent() *types.Sym {
1082	r.Sync(pkgbits.SyncLocalIdent)
1083	pkg := r.pkg()
1084	if name := r.String(); name != "" {
1085		return pkg.Lookup(name)
1086	}
1087	return nil
1088}
1089
1090func (r *reader) selector() *types.Sym {
1091	r.Sync(pkgbits.SyncSelector)
1092	pkg := r.pkg()
1093	name := r.String()
1094	if types.IsExported(name) {
1095		pkg = types.LocalPkg
1096	}
1097	return pkg.Lookup(name)
1098}
1099
1100func (r *reader) hasTypeParams() bool {
1101	return r.dict.hasTypeParams()
1102}
1103
1104func (dict *readerDict) hasTypeParams() bool {
1105	return dict != nil && len(dict.targs) != 0
1106}
1107
1108// @@@ Compiler extensions
1109
1110func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
1111	r.Sync(pkgbits.SyncFuncExt)
1112
1113	fn := name.Func
1114
1115	// XXX: Workaround because linker doesn't know how to copy Pos.
1116	if !fn.Pos().IsKnown() {
1117		fn.SetPos(name.Pos())
1118	}
1119
1120	// Normally, we only compile local functions, which saves redundant compilation work.
1121	// n.Defn is not nil for local functions, and is nil for imported function. But for
1122	// generic functions, we might have an instantiation that no other package has seen before.
1123	// So we need to be conservative and compile it again.
1124	//
1125	// That's why name.Defn is set here, so ir.VisitFuncsBottomUp can analyze function.
1126	// TODO(mdempsky,cuonglm): find a cleaner way to handle this.
1127	if name.Sym().Pkg == types.LocalPkg || r.hasTypeParams() {
1128		name.Defn = fn
1129	}
1130
1131	fn.Pragma = r.pragmaFlag()
1132	r.linkname(name)
1133
1134	if buildcfg.GOARCH == "wasm" {
1135		xmod := r.String()
1136		xname := r.String()
1137
1138		if xmod != "" && xname != "" {
1139			fn.WasmImport = &ir.WasmImport{
1140				Module: xmod,
1141				Name:   xname,
1142			}
1143		}
1144	}
1145
1146	if r.Bool() {
1147		assert(name.Defn == nil)
1148
1149		fn.ABI = obj.ABI(r.Uint64())
1150
1151		// Escape analysis.
1152		for _, f := range name.Type().RecvParams() {
1153			f.Note = r.String()
1154		}
1155
1156		if r.Bool() {
1157			fn.Inl = &ir.Inline{
1158				Cost:            int32(r.Len()),
1159				CanDelayResults: r.Bool(),
1160			}
1161			if buildcfg.Experiment.NewInliner {
1162				fn.Inl.Properties = r.String()
1163			}
1164		}
1165	} else {
1166		r.addBody(name.Func, method)
1167	}
1168	r.Sync(pkgbits.SyncEOF)
1169}
1170
1171func (r *reader) typeExt(name *ir.Name) {
1172	r.Sync(pkgbits.SyncTypeExt)
1173
1174	typ := name.Type()
1175
1176	if r.hasTypeParams() {
1177		// Set "RParams" (really type arguments here, not parameters) so
1178		// this type is treated as "fully instantiated". This ensures the
1179		// type descriptor is written out as DUPOK and method wrappers are
1180		// generated even for imported types.
1181		var targs []*types.Type
1182		targs = append(targs, r.dict.targs...)
1183		typ.SetRParams(targs)
1184	}
1185
1186	name.SetPragma(r.pragmaFlag())
1187
1188	typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
1189}
1190
1191func (r *reader) varExt(name *ir.Name) {
1192	r.Sync(pkgbits.SyncVarExt)
1193	r.linkname(name)
1194}
1195
1196func (r *reader) linkname(name *ir.Name) {
1197	assert(name.Op() == ir.ONAME)
1198	r.Sync(pkgbits.SyncLinkname)
1199
1200	if idx := r.Int64(); idx >= 0 {
1201		lsym := name.Linksym()
1202		lsym.SymIdx = int32(idx)
1203		lsym.Set(obj.AttrIndexed, true)
1204	} else {
1205		linkname := r.String()
1206		sym := name.Sym()
1207		sym.Linkname = linkname
1208		if sym.Pkg == types.LocalPkg && linkname != "" {
1209			// Mark linkname in the current package. We don't mark the
1210			// ones that are imported and propagated (e.g. through
1211			// inlining or instantiation, which are marked in their
1212			// corresponding packages). So we can tell in which package
1213			// the linkname is used (pulled), and the linker can
1214			// make a decision for allowing or disallowing it.
1215			sym.Linksym().Set(obj.AttrLinkname, true)
1216		}
1217	}
1218}
1219
1220func (r *reader) pragmaFlag() ir.PragmaFlag {
1221	r.Sync(pkgbits.SyncPragma)
1222	return ir.PragmaFlag(r.Int())
1223}
1224
1225// @@@ Function bodies
1226
1227// bodyReader tracks where the serialized IR for a local or imported,
1228// generic function's body can be found.
1229var bodyReader = map[*ir.Func]pkgReaderIndex{}
1230
1231// importBodyReader tracks where the serialized IR for an imported,
1232// static (i.e., non-generic) function body can be read.
1233var importBodyReader = map[*types.Sym]pkgReaderIndex{}
1234
1235// bodyReaderFor returns the pkgReaderIndex for reading fn's
1236// serialized IR, and whether one was found.
1237func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) {
1238	if fn.Nname.Defn != nil {
1239		pri, ok = bodyReader[fn]
1240		base.AssertfAt(ok, base.Pos, "must have bodyReader for %v", fn) // must always be available
1241	} else {
1242		pri, ok = importBodyReader[fn.Sym()]
1243	}
1244	return
1245}
1246
1247// todoDicts holds the list of dictionaries that still need their
1248// runtime dictionary objects constructed.
1249var todoDicts []func()
1250
1251// todoBodies holds the list of function bodies that still need to be
1252// constructed.
1253var todoBodies []*ir.Func
1254
1255// addBody reads a function body reference from the element bitstream,
1256// and associates it with fn.
1257func (r *reader) addBody(fn *ir.Func, method *types.Sym) {
1258	// addBody should only be called for local functions or imported
1259	// generic functions; see comment in funcExt.
1260	assert(fn.Nname.Defn != nil)
1261
1262	idx := r.Reloc(pkgbits.RelocBody)
1263
1264	pri := pkgReaderIndex{r.p, idx, r.dict, method, nil}
1265	bodyReader[fn] = pri
1266
1267	if r.curfn == nil {
1268		todoBodies = append(todoBodies, fn)
1269		return
1270	}
1271
1272	pri.funcBody(fn)
1273}
1274
1275func (pri pkgReaderIndex) funcBody(fn *ir.Func) {
1276	r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
1277	r.funcBody(fn)
1278}
1279
1280// funcBody reads a function body definition from the element
1281// bitstream, and populates fn with it.
1282func (r *reader) funcBody(fn *ir.Func) {
1283	r.curfn = fn
1284	r.closureVars = fn.ClosureVars
1285	if len(r.closureVars) != 0 && r.hasTypeParams() {
1286		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
1287	}
1288
1289	ir.WithFunc(fn, func() {
1290		r.declareParams()
1291
1292		if r.syntheticBody(fn.Pos()) {
1293			return
1294		}
1295
1296		if !r.Bool() {
1297			return
1298		}
1299
1300		body := r.stmts()
1301		if body == nil {
1302			body = []ir.Node{typecheck.Stmt(ir.NewBlockStmt(src.NoXPos, nil))}
1303		}
1304		fn.Body = body
1305		fn.Endlineno = r.pos()
1306	})
1307
1308	r.marker.WriteTo(fn)
1309}
1310
1311// syntheticBody adds a synthetic body to r.curfn if appropriate, and
1312// reports whether it did.
1313func (r *reader) syntheticBody(pos src.XPos) bool {
1314	if r.synthetic != nil {
1315		r.synthetic(pos, r)
1316		return true
1317	}
1318
1319	// If this function has type parameters and isn't shaped, then we
1320	// just tail call its corresponding shaped variant.
1321	if r.hasTypeParams() && !r.dict.shaped {
1322		r.callShaped(pos)
1323		return true
1324	}
1325
1326	return false
1327}
1328
1329// callShaped emits a tail call to r.shapedFn, passing along the
1330// arguments to the current function.
1331func (r *reader) callShaped(pos src.XPos) {
1332	shapedObj := r.dict.shapedObj
1333	assert(shapedObj != nil)
1334
1335	var shapedFn ir.Node
1336	if r.methodSym == nil {
1337		// Instantiating a generic function; shapedObj is the shaped
1338		// function itself.
1339		assert(shapedObj.Op() == ir.ONAME && shapedObj.Class == ir.PFUNC)
1340		shapedFn = shapedObj
1341	} else {
1342		// Instantiating a generic type's method; shapedObj is the shaped
1343		// type, so we need to select it's corresponding method.
1344		shapedFn = shapedMethodExpr(pos, shapedObj, r.methodSym)
1345	}
1346
1347	params := r.syntheticArgs()
1348
1349	// Construct the arguments list: receiver (if any), then runtime
1350	// dictionary, and finally normal parameters.
1351	//
1352	// Note: For simplicity, shaped methods are added as normal methods
1353	// on their shaped types. So existing code (e.g., packages ir and
1354	// typecheck) expects the shaped type to appear as the receiver
1355	// parameter (or first parameter, as a method expression). Hence
1356	// putting the dictionary parameter after that is the least invasive
1357	// solution at the moment.
1358	var args ir.Nodes
1359	if r.methodSym != nil {
1360		args.Append(params[0])
1361		params = params[1:]
1362	}
1363	args.Append(typecheck.Expr(ir.NewAddrExpr(pos, r.p.dictNameOf(r.dict))))
1364	args.Append(params...)
1365
1366	r.syntheticTailCall(pos, shapedFn, args)
1367}
1368
1369// syntheticArgs returns the recvs and params arguments passed to the
1370// current function.
1371func (r *reader) syntheticArgs() ir.Nodes {
1372	sig := r.curfn.Nname.Type()
1373	return ir.ToNodes(r.curfn.Dcl[:sig.NumRecvs()+sig.NumParams()])
1374}
1375
1376// syntheticTailCall emits a tail call to fn, passing the given
1377// arguments list.
1378func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) {
1379	// Mark the function as a wrapper so it doesn't show up in stack
1380	// traces.
1381	r.curfn.SetWrapper(true)
1382
1383	call := typecheck.Call(pos, fn, args, fn.Type().IsVariadic()).(*ir.CallExpr)
1384
1385	var stmt ir.Node
1386	if fn.Type().NumResults() != 0 {
1387		stmt = typecheck.Stmt(ir.NewReturnStmt(pos, []ir.Node{call}))
1388	} else {
1389		stmt = call
1390	}
1391	r.curfn.Body.Append(stmt)
1392}
1393
1394// dictNameOf returns the runtime dictionary corresponding to dict.
1395func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
1396	pos := base.AutogeneratedPos
1397
1398	// Check that we only instantiate runtime dictionaries with real types.
1399	base.AssertfAt(!dict.shaped, pos, "runtime dictionary of shaped object %v", dict.baseSym)
1400
1401	sym := dict.baseSym.Pkg.Lookup(objabi.GlobalDictPrefix + "." + dict.baseSym.Name)
1402	if sym.Def != nil {
1403		return sym.Def.(*ir.Name)
1404	}
1405
1406	name := ir.NewNameAt(pos, sym, dict.varType())
1407	name.Class = ir.PEXTERN
1408	sym.Def = name // break cycles with mutual subdictionaries
1409
1410	lsym := name.Linksym()
1411	ot := 0
1412
1413	assertOffset := func(section string, offset int) {
1414		base.AssertfAt(ot == offset*types.PtrSize, pos, "writing section %v at offset %v, but it should be at %v*%v", section, ot, offset, types.PtrSize)
1415	}
1416
1417	assertOffset("type param method exprs", dict.typeParamMethodExprsOffset())
1418	for _, info := range dict.typeParamMethodExprs {
1419		typeParam := dict.targs[info.typeParamIdx]
1420		method := typecheck.NewMethodExpr(pos, typeParam, info.method)
1421
1422		rsym := method.FuncName().Linksym()
1423		assert(rsym.ABI() == obj.ABIInternal) // must be ABIInternal; see ir.OCFUNC in ssagen/ssa.go
1424
1425		ot = objw.SymPtr(lsym, ot, rsym, 0)
1426	}
1427
1428	assertOffset("subdictionaries", dict.subdictsOffset())
1429	for _, info := range dict.subdicts {
1430		explicits := pr.typListIdx(info.explicits, dict)
1431
1432		// Careful: Due to subdictionary cycles, name may not be fully
1433		// initialized yet.
1434		name := pr.objDictName(info.idx, dict.targs, explicits)
1435
1436		ot = objw.SymPtr(lsym, ot, name.Linksym(), 0)
1437	}
1438
1439	assertOffset("rtypes", dict.rtypesOffset())
1440	for _, info := range dict.rtypes {
1441		typ := pr.typIdx(info, dict, true)
1442		ot = objw.SymPtr(lsym, ot, reflectdata.TypeLinksym(typ), 0)
1443
1444		// TODO(mdempsky): Double check this.
1445		reflectdata.MarkTypeUsedInInterface(typ, lsym)
1446	}
1447
1448	// For each (typ, iface) pair, we write the *runtime.itab pointer
1449	// for the pair. For pairs that don't actually require an itab
1450	// (i.e., typ is an interface, or iface is an empty interface), we
1451	// write a nil pointer instead. This is wasteful, but rare in
1452	// practice (e.g., instantiating a type parameter with an interface
1453	// type).
1454	assertOffset("itabs", dict.itabsOffset())
1455	for _, info := range dict.itabs {
1456		typ := pr.typIdx(info.typ, dict, true)
1457		iface := pr.typIdx(info.iface, dict, true)
1458
1459		if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
1460			ot = objw.SymPtr(lsym, ot, reflectdata.ITabLsym(typ, iface), 0)
1461		} else {
1462			ot += types.PtrSize
1463		}
1464
1465		// TODO(mdempsky): Double check this.
1466		reflectdata.MarkTypeUsedInInterface(typ, lsym)
1467		reflectdata.MarkTypeUsedInInterface(iface, lsym)
1468	}
1469
1470	objw.Global(lsym, int32(ot), obj.DUPOK|obj.RODATA)
1471
1472	return name
1473}
1474
1475// typeParamMethodExprsOffset returns the offset of the runtime
1476// dictionary's type parameter method expressions section, in words.
1477func (dict *readerDict) typeParamMethodExprsOffset() int {
1478	return 0
1479}
1480
1481// subdictsOffset returns the offset of the runtime dictionary's
1482// subdictionary section, in words.
1483func (dict *readerDict) subdictsOffset() int {
1484	return dict.typeParamMethodExprsOffset() + len(dict.typeParamMethodExprs)
1485}
1486
1487// rtypesOffset returns the offset of the runtime dictionary's rtypes
1488// section, in words.
1489func (dict *readerDict) rtypesOffset() int {
1490	return dict.subdictsOffset() + len(dict.subdicts)
1491}
1492
1493// itabsOffset returns the offset of the runtime dictionary's itabs
1494// section, in words.
1495func (dict *readerDict) itabsOffset() int {
1496	return dict.rtypesOffset() + len(dict.rtypes)
1497}
1498
1499// numWords returns the total number of words that comprise dict's
1500// runtime dictionary variable.
1501func (dict *readerDict) numWords() int64 {
1502	return int64(dict.itabsOffset() + len(dict.itabs))
1503}
1504
1505// varType returns the type of dict's runtime dictionary variable.
1506func (dict *readerDict) varType() *types.Type {
1507	return types.NewArray(types.Types[types.TUINTPTR], dict.numWords())
1508}
1509
1510func (r *reader) declareParams() {
1511	r.curfn.DeclareParams(!r.funarghack)
1512
1513	for _, name := range r.curfn.Dcl {
1514		if name.Sym().Name == dictParamName {
1515			r.dictParam = name
1516			continue
1517		}
1518
1519		r.addLocal(name)
1520	}
1521}
1522
1523func (r *reader) addLocal(name *ir.Name) {
1524	if r.synthetic == nil {
1525		r.Sync(pkgbits.SyncAddLocal)
1526		if r.p.SyncMarkers() {
1527			want := r.Int()
1528			if have := len(r.locals); have != want {
1529				base.FatalfAt(name.Pos(), "locals table has desynced")
1530			}
1531		}
1532		r.varDictIndex(name)
1533	}
1534
1535	r.locals = append(r.locals, name)
1536}
1537
1538func (r *reader) useLocal() *ir.Name {
1539	r.Sync(pkgbits.SyncUseObjLocal)
1540	if r.Bool() {
1541		return r.locals[r.Len()]
1542	}
1543	return r.closureVars[r.Len()]
1544}
1545
1546func (r *reader) openScope() {
1547	r.Sync(pkgbits.SyncOpenScope)
1548	pos := r.pos()
1549
1550	if base.Flag.Dwarf {
1551		r.scopeVars = append(r.scopeVars, len(r.curfn.Dcl))
1552		r.marker.Push(pos)
1553	}
1554}
1555
1556func (r *reader) closeScope() {
1557	r.Sync(pkgbits.SyncCloseScope)
1558	r.lastCloseScopePos = r.pos()
1559
1560	r.closeAnotherScope()
1561}
1562
1563// closeAnotherScope is like closeScope, but it reuses the same mark
1564// position as the last closeScope call. This is useful for "for" and
1565// "if" statements, as their implicit blocks always end at the same
1566// position as an explicit block.
1567func (r *reader) closeAnotherScope() {
1568	r.Sync(pkgbits.SyncCloseAnotherScope)
1569
1570	if base.Flag.Dwarf {
1571		scopeVars := r.scopeVars[len(r.scopeVars)-1]
1572		r.scopeVars = r.scopeVars[:len(r.scopeVars)-1]
1573
1574		// Quirkish: noder decides which scopes to keep before
1575		// typechecking, whereas incremental typechecking during IR
1576		// construction can result in new autotemps being allocated. To
1577		// produce identical output, we ignore autotemps here for the
1578		// purpose of deciding whether to retract the scope.
1579		//
1580		// This is important for net/http/fcgi, because it contains:
1581		//
1582		//	var body io.ReadCloser
1583		//	if len(content) > 0 {
1584		//		body, req.pw = io.Pipe()
1585		//	} else { … }
1586		//
1587		// Notably, io.Pipe is inlinable, and inlining it introduces a ~R0
1588		// variable at the call site.
1589		//
1590		// Noder does not preserve the scope where the io.Pipe() call
1591		// resides, because it doesn't contain any declared variables in
1592		// source. So the ~R0 variable ends up being assigned to the
1593		// enclosing scope instead.
1594		//
1595		// However, typechecking this assignment also introduces
1596		// autotemps, because io.Pipe's results need conversion before
1597		// they can be assigned to their respective destination variables.
1598		//
1599		// TODO(mdempsky): We should probably just keep all scopes, and
1600		// let dwarfgen take care of pruning them instead.
1601		retract := true
1602		for _, n := range r.curfn.Dcl[scopeVars:] {
1603			if !n.AutoTemp() {
1604				retract = false
1605				break
1606			}
1607		}
1608
1609		if retract {
1610			// no variables were declared in this scope, so we can retract it.
1611			r.marker.Unpush()
1612		} else {
1613			r.marker.Pop(r.lastCloseScopePos)
1614		}
1615	}
1616}
1617
1618// @@@ Statements
1619
1620func (r *reader) stmt() ir.Node {
1621	return block(r.stmts())
1622}
1623
1624func block(stmts []ir.Node) ir.Node {
1625	switch len(stmts) {
1626	case 0:
1627		return nil
1628	case 1:
1629		return stmts[0]
1630	default:
1631		return ir.NewBlockStmt(stmts[0].Pos(), stmts)
1632	}
1633}
1634
1635func (r *reader) stmts() ir.Nodes {
1636	assert(ir.CurFunc == r.curfn)
1637	var res ir.Nodes
1638
1639	r.Sync(pkgbits.SyncStmts)
1640	for {
1641		tag := codeStmt(r.Code(pkgbits.SyncStmt1))
1642		if tag == stmtEnd {
1643			r.Sync(pkgbits.SyncStmtsEnd)
1644			return res
1645		}
1646
1647		if n := r.stmt1(tag, &res); n != nil {
1648			res.Append(typecheck.Stmt(n))
1649		}
1650	}
1651}
1652
1653func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node {
1654	var label *types.Sym
1655	if n := len(*out); n > 0 {
1656		if ls, ok := (*out)[n-1].(*ir.LabelStmt); ok {
1657			label = ls.Label
1658		}
1659	}
1660
1661	switch tag {
1662	default:
1663		panic("unexpected statement")
1664
1665	case stmtAssign:
1666		pos := r.pos()
1667		names, lhs := r.assignList()
1668		rhs := r.multiExpr()
1669
1670		if len(rhs) == 0 {
1671			for _, name := range names {
1672				as := ir.NewAssignStmt(pos, name, nil)
1673				as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, name))
1674				out.Append(typecheck.Stmt(as))
1675			}
1676			return nil
1677		}
1678
1679		if len(lhs) == 1 && len(rhs) == 1 {
1680			n := ir.NewAssignStmt(pos, lhs[0], rhs[0])
1681			n.Def = r.initDefn(n, names)
1682			return n
1683		}
1684
1685		n := ir.NewAssignListStmt(pos, ir.OAS2, lhs, rhs)
1686		n.Def = r.initDefn(n, names)
1687		return n
1688
1689	case stmtAssignOp:
1690		op := r.op()
1691		lhs := r.expr()
1692		pos := r.pos()
1693		rhs := r.expr()
1694		return ir.NewAssignOpStmt(pos, op, lhs, rhs)
1695
1696	case stmtIncDec:
1697		op := r.op()
1698		lhs := r.expr()
1699		pos := r.pos()
1700		n := ir.NewAssignOpStmt(pos, op, lhs, ir.NewOne(pos, lhs.Type()))
1701		n.IncDec = true
1702		return n
1703
1704	case stmtBlock:
1705		out.Append(r.blockStmt()...)
1706		return nil
1707
1708	case stmtBranch:
1709		pos := r.pos()
1710		op := r.op()
1711		sym := r.optLabel()
1712		return ir.NewBranchStmt(pos, op, sym)
1713
1714	case stmtCall:
1715		pos := r.pos()
1716		op := r.op()
1717		call := r.expr()
1718		stmt := ir.NewGoDeferStmt(pos, op, call)
1719		if op == ir.ODEFER {
1720			x := r.optExpr()
1721			if x != nil {
1722				stmt.DeferAt = x.(ir.Expr)
1723			}
1724		}
1725		return stmt
1726
1727	case stmtExpr:
1728		return r.expr()
1729
1730	case stmtFor:
1731		return r.forStmt(label)
1732
1733	case stmtIf:
1734		return r.ifStmt()
1735
1736	case stmtLabel:
1737		pos := r.pos()
1738		sym := r.label()
1739		return ir.NewLabelStmt(pos, sym)
1740
1741	case stmtReturn:
1742		pos := r.pos()
1743		results := r.multiExpr()
1744		return ir.NewReturnStmt(pos, results)
1745
1746	case stmtSelect:
1747		return r.selectStmt(label)
1748
1749	case stmtSend:
1750		pos := r.pos()
1751		ch := r.expr()
1752		value := r.expr()
1753		return ir.NewSendStmt(pos, ch, value)
1754
1755	case stmtSwitch:
1756		return r.switchStmt(label)
1757	}
1758}
1759
1760func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
1761	lhs := make([]ir.Node, r.Len())
1762	var names []*ir.Name
1763
1764	for i := range lhs {
1765		expr, def := r.assign()
1766		lhs[i] = expr
1767		if def {
1768			names = append(names, expr.(*ir.Name))
1769		}
1770	}
1771
1772	return names, lhs
1773}
1774
1775// assign returns an assignee expression. It also reports whether the
1776// returned expression is a newly declared variable.
1777func (r *reader) assign() (ir.Node, bool) {
1778	switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
1779	default:
1780		panic("unhandled assignee expression")
1781
1782	case assignBlank:
1783		return typecheck.AssignExpr(ir.BlankNode), false
1784
1785	case assignDef:
1786		pos := r.pos()
1787		setBasePos(pos) // test/fixedbugs/issue49767.go depends on base.Pos being set for the r.typ() call here, ugh
1788		name := r.curfn.NewLocal(pos, r.localIdent(), r.typ())
1789		r.addLocal(name)
1790		return name, true
1791
1792	case assignExpr:
1793		return r.expr(), false
1794	}
1795}
1796
1797func (r *reader) blockStmt() []ir.Node {
1798	r.Sync(pkgbits.SyncBlockStmt)
1799	r.openScope()
1800	stmts := r.stmts()
1801	r.closeScope()
1802	return stmts
1803}
1804
1805func (r *reader) forStmt(label *types.Sym) ir.Node {
1806	r.Sync(pkgbits.SyncForStmt)
1807
1808	r.openScope()
1809
1810	if r.Bool() {
1811		pos := r.pos()
1812		rang := ir.NewRangeStmt(pos, nil, nil, nil, nil, false)
1813		rang.Label = label
1814
1815		names, lhs := r.assignList()
1816		if len(lhs) >= 1 {
1817			rang.Key = lhs[0]
1818			if len(lhs) >= 2 {
1819				rang.Value = lhs[1]
1820			}
1821		}
1822		rang.Def = r.initDefn(rang, names)
1823
1824		rang.X = r.expr()
1825		if rang.X.Type().IsMap() {
1826			rang.RType = r.rtype(pos)
1827		}
1828		if rang.Key != nil && !ir.IsBlank(rang.Key) {
1829			rang.KeyTypeWord, rang.KeySrcRType = r.convRTTI(pos)
1830		}
1831		if rang.Value != nil && !ir.IsBlank(rang.Value) {
1832			rang.ValueTypeWord, rang.ValueSrcRType = r.convRTTI(pos)
1833		}
1834
1835		rang.Body = r.blockStmt()
1836		rang.DistinctVars = r.Bool()
1837		r.closeAnotherScope()
1838
1839		return rang
1840	}
1841
1842	pos := r.pos()
1843	init := r.stmt()
1844	cond := r.optExpr()
1845	post := r.stmt()
1846	body := r.blockStmt()
1847	perLoopVars := r.Bool()
1848	r.closeAnotherScope()
1849
1850	if ir.IsConst(cond, constant.Bool) && !ir.BoolVal(cond) {
1851		return init // simplify "for init; false; post { ... }" into "init"
1852	}
1853
1854	stmt := ir.NewForStmt(pos, init, cond, post, body, perLoopVars)
1855	stmt.Label = label
1856	return stmt
1857}
1858
1859func (r *reader) ifStmt() ir.Node {
1860	r.Sync(pkgbits.SyncIfStmt)
1861	r.openScope()
1862	pos := r.pos()
1863	init := r.stmts()
1864	cond := r.expr()
1865	staticCond := r.Int()
1866	var then, els []ir.Node
1867	if staticCond >= 0 {
1868		then = r.blockStmt()
1869	} else {
1870		r.lastCloseScopePos = r.pos()
1871	}
1872	if staticCond <= 0 {
1873		els = r.stmts()
1874	}
1875	r.closeAnotherScope()
1876
1877	if staticCond != 0 {
1878		// We may have removed a dead return statement, which can trip up
1879		// later passes (#62211). To avoid confusion, we instead flatten
1880		// the if statement into a block.
1881
1882		if cond.Op() != ir.OLITERAL {
1883			init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, ir.BlankNode, cond))) // for side effects
1884		}
1885		init.Append(then...)
1886		init.Append(els...)
1887		return block(init)
1888	}
1889
1890	n := ir.NewIfStmt(pos, cond, then, els)
1891	n.SetInit(init)
1892	return n
1893}
1894
1895func (r *reader) selectStmt(label *types.Sym) ir.Node {
1896	r.Sync(pkgbits.SyncSelectStmt)
1897
1898	pos := r.pos()
1899	clauses := make([]*ir.CommClause, r.Len())
1900	for i := range clauses {
1901		if i > 0 {
1902			r.closeScope()
1903		}
1904		r.openScope()
1905
1906		pos := r.pos()
1907		comm := r.stmt()
1908		body := r.stmts()
1909
1910		// "case i = <-c: ..." may require an implicit conversion (e.g.,
1911		// see fixedbugs/bug312.go). Currently, typecheck throws away the
1912		// implicit conversion and relies on it being reinserted later,
1913		// but that would lose any explicit RTTI operands too. To preserve
1914		// RTTI, we rewrite this as "case tmp := <-c: i = tmp; ...".
1915		if as, ok := comm.(*ir.AssignStmt); ok && as.Op() == ir.OAS && !as.Def {
1916			if conv, ok := as.Y.(*ir.ConvExpr); ok && conv.Op() == ir.OCONVIFACE {
1917				base.AssertfAt(conv.Implicit(), conv.Pos(), "expected implicit conversion: %v", conv)
1918
1919				recv := conv.X
1920				base.AssertfAt(recv.Op() == ir.ORECV, recv.Pos(), "expected receive expression: %v", recv)
1921
1922				tmp := r.temp(pos, recv.Type())
1923
1924				// Replace comm with `tmp := <-c`.
1925				tmpAs := ir.NewAssignStmt(pos, tmp, recv)
1926				tmpAs.Def = true
1927				tmpAs.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
1928				comm = tmpAs
1929
1930				// Change original assignment to `i = tmp`, and prepend to body.
1931				conv.X = tmp
1932				body = append([]ir.Node{as}, body...)
1933			}
1934		}
1935
1936		// multiExpr will have desugared a comma-ok receive expression
1937		// into a separate statement. However, the rest of the compiler
1938		// expects comm to be the OAS2RECV statement itself, so we need to
1939		// shuffle things around to fit that pattern.
1940		if as2, ok := comm.(*ir.AssignListStmt); ok && as2.Op() == ir.OAS2 {
1941			init := ir.TakeInit(as2.Rhs[0])
1942			base.AssertfAt(len(init) == 1 && init[0].Op() == ir.OAS2RECV, as2.Pos(), "unexpected assignment: %+v", as2)
1943
1944			comm = init[0]
1945			body = append([]ir.Node{as2}, body...)
1946		}
1947
1948		clauses[i] = ir.NewCommStmt(pos, comm, body)
1949	}
1950	if len(clauses) > 0 {
1951		r.closeScope()
1952	}
1953	n := ir.NewSelectStmt(pos, clauses)
1954	n.Label = label
1955	return n
1956}
1957
1958func (r *reader) switchStmt(label *types.Sym) ir.Node {
1959	r.Sync(pkgbits.SyncSwitchStmt)
1960
1961	r.openScope()
1962	pos := r.pos()
1963	init := r.stmt()
1964
1965	var tag ir.Node
1966	var ident *ir.Ident
1967	var iface *types.Type
1968	if r.Bool() {
1969		pos := r.pos()
1970		if r.Bool() {
1971			ident = ir.NewIdent(r.pos(), r.localIdent())
1972		}
1973		x := r.expr()
1974		iface = x.Type()
1975		tag = ir.NewTypeSwitchGuard(pos, ident, x)
1976	} else {
1977		tag = r.optExpr()
1978	}
1979
1980	clauses := make([]*ir.CaseClause, r.Len())
1981	for i := range clauses {
1982		if i > 0 {
1983			r.closeScope()
1984		}
1985		r.openScope()
1986
1987		pos := r.pos()
1988		var cases, rtypes []ir.Node
1989		if iface != nil {
1990			cases = make([]ir.Node, r.Len())
1991			if len(cases) == 0 {
1992				cases = nil // TODO(mdempsky): Unclear if this matters.
1993			}
1994			for i := range cases {
1995				if r.Bool() { // case nil
1996					cases[i] = typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
1997				} else {
1998					cases[i] = r.exprType()
1999				}
2000			}
2001		} else {
2002			cases = r.exprList()
2003
2004			// For `switch { case any(true): }` (e.g., issue 3980 in
2005			// test/switch.go), the backend still creates a mixed bool/any
2006			// comparison, and we need to explicitly supply the RTTI for the
2007			// comparison.
2008			//
2009			// TODO(mdempsky): Change writer.go to desugar "switch {" into
2010			// "switch true {", which we already handle correctly.
2011			if tag == nil {
2012				for i, cas := range cases {
2013					if cas.Type().IsEmptyInterface() {
2014						for len(rtypes) < i {
2015							rtypes = append(rtypes, nil)
2016						}
2017						rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), types.Types[types.TBOOL]))
2018					}
2019				}
2020			}
2021		}
2022
2023		clause := ir.NewCaseStmt(pos, cases, nil)
2024		clause.RTypes = rtypes
2025
2026		if ident != nil {
2027			name := r.curfn.NewLocal(r.pos(), ident.Sym(), r.typ())
2028			r.addLocal(name)
2029			clause.Var = name
2030			name.Defn = tag
2031		}
2032
2033		clause.Body = r.stmts()
2034		clauses[i] = clause
2035	}
2036	if len(clauses) > 0 {
2037		r.closeScope()
2038	}
2039	r.closeScope()
2040
2041	n := ir.NewSwitchStmt(pos, tag, clauses)
2042	n.Label = label
2043	if init != nil {
2044		n.SetInit([]ir.Node{init})
2045	}
2046	return n
2047}
2048
2049func (r *reader) label() *types.Sym {
2050	r.Sync(pkgbits.SyncLabel)
2051	name := r.String()
2052	if r.inlCall != nil {
2053		name = fmt.Sprintf("~%s·%d", name, inlgen)
2054	}
2055	return typecheck.Lookup(name)
2056}
2057
2058func (r *reader) optLabel() *types.Sym {
2059	r.Sync(pkgbits.SyncOptLabel)
2060	if r.Bool() {
2061		return r.label()
2062	}
2063	return nil
2064}
2065
2066// initDefn marks the given names as declared by defn and populates
2067// its Init field with ODCL nodes. It then reports whether any names
2068// were so declared, which can be used to initialize defn.Def.
2069func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool {
2070	if len(names) == 0 {
2071		return false
2072	}
2073
2074	init := make([]ir.Node, len(names))
2075	for i, name := range names {
2076		name.Defn = defn
2077		init[i] = ir.NewDecl(name.Pos(), ir.ODCL, name)
2078	}
2079	defn.SetInit(init)
2080	return true
2081}
2082
2083// @@@ Expressions
2084
2085// expr reads and returns a typechecked expression.
2086func (r *reader) expr() (res ir.Node) {
2087	defer func() {
2088		if res != nil && res.Typecheck() == 0 {
2089			base.FatalfAt(res.Pos(), "%v missed typecheck", res)
2090		}
2091	}()
2092
2093	switch tag := codeExpr(r.Code(pkgbits.SyncExpr)); tag {
2094	default:
2095		panic("unhandled expression")
2096
2097	case exprLocal:
2098		return typecheck.Expr(r.useLocal())
2099
2100	case exprGlobal:
2101		// Callee instead of Expr allows builtins
2102		// TODO(mdempsky): Handle builtins directly in exprCall, like method calls?
2103		return typecheck.Callee(r.obj())
2104
2105	case exprFuncInst:
2106		origPos, pos := r.origPos()
2107		wrapperFn, baseFn, dictPtr := r.funcInst(pos)
2108		if wrapperFn != nil {
2109			return wrapperFn
2110		}
2111		return r.curry(origPos, false, baseFn, dictPtr, nil)
2112
2113	case exprConst:
2114		pos := r.pos()
2115		typ := r.typ()
2116		val := FixValue(typ, r.Value())
2117		return ir.NewBasicLit(pos, typ, val)
2118
2119	case exprZero:
2120		pos := r.pos()
2121		typ := r.typ()
2122		return ir.NewZero(pos, typ)
2123
2124	case exprCompLit:
2125		return r.compLit()
2126
2127	case exprFuncLit:
2128		return r.funcLit()
2129
2130	case exprFieldVal:
2131		x := r.expr()
2132		pos := r.pos()
2133		sym := r.selector()
2134
2135		return typecheck.XDotField(pos, x, sym)
2136
2137	case exprMethodVal:
2138		recv := r.expr()
2139		origPos, pos := r.origPos()
2140		wrapperFn, baseFn, dictPtr := r.methodExpr()
2141
2142		// For simple wrapperFn values, the existing machinery for creating
2143		// and deduplicating wrapperFn value wrappers still works fine.
2144		if wrapperFn, ok := wrapperFn.(*ir.SelectorExpr); ok && wrapperFn.Op() == ir.OMETHEXPR {
2145			// The receiver expression we constructed may have a shape type.
2146			// For example, in fixedbugs/issue54343.go, `New[int]()` is
2147			// constructed as `New[go.shape.int](&.dict.New[int])`, which
2148			// has type `*T[go.shape.int]`, not `*T[int]`.
2149			//
2150			// However, the method we want to select here is `(*T[int]).M`,
2151			// not `(*T[go.shape.int]).M`, so we need to manually convert
2152			// the type back so that the OXDOT resolves correctly.
2153			//
2154			// TODO(mdempsky): Logically it might make more sense for
2155			// exprCall to take responsibility for setting a non-shaped
2156			// result type, but this is the only place where we care
2157			// currently. And only because existing ir.OMETHVALUE backend
2158			// code relies on n.X.Type() instead of n.Selection.Recv().Type
2159			// (because the latter is types.FakeRecvType() in the case of
2160			// interface method values).
2161			//
2162			if recv.Type().HasShape() {
2163				typ := wrapperFn.Type().Param(0).Type
2164				if !types.Identical(typ, recv.Type()) {
2165					base.FatalfAt(wrapperFn.Pos(), "receiver %L does not match %L", recv, wrapperFn)
2166				}
2167				recv = typecheck.Expr(ir.NewConvExpr(recv.Pos(), ir.OCONVNOP, typ, recv))
2168			}
2169
2170			n := typecheck.XDotMethod(pos, recv, wrapperFn.Sel, false)
2171
2172			// As a consistency check here, we make sure "n" selected the
2173			// same method (represented by a types.Field) that wrapperFn
2174			// selected. However, for anonymous receiver types, there can be
2175			// multiple such types.Field instances (#58563). So we may need
2176			// to fallback to making sure Sym and Type (including the
2177			// receiver parameter's type) match.
2178			if n.Selection != wrapperFn.Selection {
2179				assert(n.Selection.Sym == wrapperFn.Selection.Sym)
2180				assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
2181				assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
2182			}
2183
2184			wrapper := methodValueWrapper{
2185				rcvr:   n.X.Type(),
2186				method: n.Selection,
2187			}
2188
2189			if r.importedDef() {
2190				haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
2191			} else {
2192				needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
2193			}
2194			return n
2195		}
2196
2197		// For more complicated method expressions, we construct a
2198		// function literal wrapper.
2199		return r.curry(origPos, true, baseFn, recv, dictPtr)
2200
2201	case exprMethodExpr:
2202		recv := r.typ()
2203
2204		implicits := make([]int, r.Len())
2205		for i := range implicits {
2206			implicits[i] = r.Len()
2207		}
2208		var deref, addr bool
2209		if r.Bool() {
2210			deref = true
2211		} else if r.Bool() {
2212			addr = true
2213		}
2214
2215		origPos, pos := r.origPos()
2216		wrapperFn, baseFn, dictPtr := r.methodExpr()
2217
2218		// If we already have a wrapper and don't need to do anything with
2219		// it, we can just return the wrapper directly.
2220		//
2221		// N.B., we use implicits/deref/addr here as the source of truth
2222		// rather than types.Identical, because the latter can be confused
2223		// by tricky promoted methods (e.g., typeparam/mdempsky/21.go).
2224		if wrapperFn != nil && len(implicits) == 0 && !deref && !addr {
2225			if !types.Identical(recv, wrapperFn.Type().Param(0).Type) {
2226				base.FatalfAt(pos, "want receiver type %v, but have method %L", recv, wrapperFn)
2227			}
2228			return wrapperFn
2229		}
2230
2231		// Otherwise, if the wrapper function is a static method
2232		// expression (OMETHEXPR) and the receiver type is unshaped, then
2233		// we can rely on a statically generated wrapper being available.
2234		if method, ok := wrapperFn.(*ir.SelectorExpr); ok && method.Op() == ir.OMETHEXPR && !recv.HasShape() {
2235			return typecheck.NewMethodExpr(pos, recv, method.Sel)
2236		}
2237
2238		return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
2239
2240	case exprIndex:
2241		x := r.expr()
2242		pos := r.pos()
2243		index := r.expr()
2244		n := typecheck.Expr(ir.NewIndexExpr(pos, x, index))
2245		switch n.Op() {
2246		case ir.OINDEXMAP:
2247			n := n.(*ir.IndexExpr)
2248			n.RType = r.rtype(pos)
2249		}
2250		return n
2251
2252	case exprSlice:
2253		x := r.expr()
2254		pos := r.pos()
2255		var index [3]ir.Node
2256		for i := range index {
2257			index[i] = r.optExpr()
2258		}
2259		op := ir.OSLICE
2260		if index[2] != nil {
2261			op = ir.OSLICE3
2262		}
2263		return typecheck.Expr(ir.NewSliceExpr(pos, op, x, index[0], index[1], index[2]))
2264
2265	case exprAssert:
2266		x := r.expr()
2267		pos := r.pos()
2268		typ := r.exprType()
2269		srcRType := r.rtype(pos)
2270
2271		// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
2272		if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
2273			assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
2274			assert.SrcRType = srcRType
2275			assert.ITab = typ.ITab
2276			return typed(typ.Type(), assert)
2277		}
2278		return typecheck.Expr(ir.NewTypeAssertExpr(pos, x, typ.Type()))
2279
2280	case exprUnaryOp:
2281		op := r.op()
2282		pos := r.pos()
2283		x := r.expr()
2284
2285		switch op {
2286		case ir.OADDR:
2287			return typecheck.Expr(typecheck.NodAddrAt(pos, x))
2288		case ir.ODEREF:
2289			return typecheck.Expr(ir.NewStarExpr(pos, x))
2290		}
2291		return typecheck.Expr(ir.NewUnaryExpr(pos, op, x))
2292
2293	case exprBinaryOp:
2294		op := r.op()
2295		x := r.expr()
2296		pos := r.pos()
2297		y := r.expr()
2298
2299		switch op {
2300		case ir.OANDAND, ir.OOROR:
2301			return typecheck.Expr(ir.NewLogicalExpr(pos, op, x, y))
2302		case ir.OLSH, ir.ORSH:
2303			// Untyped rhs of non-constant shift, e.g. x << 1.0.
2304			// If we have a constant value, it must be an int >= 0.
2305			if ir.IsConstNode(y) {
2306				val := constant.ToInt(y.Val())
2307				assert(val.Kind() == constant.Int && constant.Sign(val) >= 0)
2308			}
2309		}
2310		return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
2311
2312	case exprRecv:
2313		x := r.expr()
2314		pos := r.pos()
2315		for i, n := 0, r.Len(); i < n; i++ {
2316			x = Implicit(typecheck.DotField(pos, x, r.Len()))
2317		}
2318		if r.Bool() { // needs deref
2319			x = Implicit(Deref(pos, x.Type().Elem(), x))
2320		} else if r.Bool() { // needs addr
2321			x = Implicit(Addr(pos, x))
2322		}
2323		return x
2324
2325	case exprCall:
2326		var fun ir.Node
2327		var args ir.Nodes
2328		if r.Bool() { // method call
2329			recv := r.expr()
2330			_, method, dictPtr := r.methodExpr()
2331
2332			if recv.Type().IsInterface() && method.Op() == ir.OMETHEXPR {
2333				method := method.(*ir.SelectorExpr)
2334
2335				// The compiler backend (e.g., devirtualization) handle
2336				// OCALLINTER/ODOTINTER better than OCALLFUNC/OMETHEXPR for
2337				// interface calls, so we prefer to continue constructing
2338				// calls that way where possible.
2339				//
2340				// There are also corner cases where semantically it's perhaps
2341				// significant; e.g., fixedbugs/issue15975.go, #38634, #52025.
2342
2343				fun = typecheck.XDotMethod(method.Pos(), recv, method.Sel, true)
2344			} else {
2345				if recv.Type().IsInterface() {
2346					// N.B., this happens currently for typeparam/issue51521.go
2347					// and typeparam/typeswitch3.go.
2348					if base.Flag.LowerM != 0 {
2349						base.WarnfAt(method.Pos(), "imprecise interface call")
2350					}
2351				}
2352
2353				fun = method
2354				args.Append(recv)
2355			}
2356			if dictPtr != nil {
2357				args.Append(dictPtr)
2358			}
2359		} else if r.Bool() { // call to instanced function
2360			pos := r.pos()
2361			_, shapedFn, dictPtr := r.funcInst(pos)
2362			fun = shapedFn
2363			args.Append(dictPtr)
2364		} else {
2365			fun = r.expr()
2366		}
2367		pos := r.pos()
2368		args.Append(r.multiExpr()...)
2369		dots := r.Bool()
2370		n := typecheck.Call(pos, fun, args, dots)
2371		switch n.Op() {
2372		case ir.OAPPEND:
2373			n := n.(*ir.CallExpr)
2374			n.RType = r.rtype(pos)
2375			// For append(a, b...), we don't need the implicit conversion. The typechecker already
2376			// ensured that a and b are both slices with the same base type, or []byte and string.
2377			if n.IsDDD {
2378				if conv, ok := n.Args[1].(*ir.ConvExpr); ok && conv.Op() == ir.OCONVNOP && conv.Implicit() {
2379					n.Args[1] = conv.X
2380				}
2381			}
2382		case ir.OCOPY:
2383			n := n.(*ir.BinaryExpr)
2384			n.RType = r.rtype(pos)
2385		case ir.ODELETE:
2386			n := n.(*ir.CallExpr)
2387			n.RType = r.rtype(pos)
2388		case ir.OUNSAFESLICE:
2389			n := n.(*ir.BinaryExpr)
2390			n.RType = r.rtype(pos)
2391		}
2392		return n
2393
2394	case exprMake:
2395		pos := r.pos()
2396		typ := r.exprType()
2397		extra := r.exprs()
2398		n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
2399		n.RType = r.rtype(pos)
2400		return n
2401
2402	case exprNew:
2403		pos := r.pos()
2404		typ := r.exprType()
2405		return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
2406
2407	case exprSizeof:
2408		return ir.NewUintptr(r.pos(), r.typ().Size())
2409
2410	case exprAlignof:
2411		return ir.NewUintptr(r.pos(), r.typ().Alignment())
2412
2413	case exprOffsetof:
2414		pos := r.pos()
2415		typ := r.typ()
2416		types.CalcSize(typ)
2417
2418		var offset int64
2419		for i := r.Len(); i >= 0; i-- {
2420			field := typ.Field(r.Len())
2421			offset += field.Offset
2422			typ = field.Type
2423		}
2424
2425		return ir.NewUintptr(pos, offset)
2426
2427	case exprReshape:
2428		typ := r.typ()
2429		x := r.expr()
2430
2431		if types.IdenticalStrict(x.Type(), typ) {
2432			return x
2433		}
2434
2435		// Comparison expressions are constructed as "untyped bool" still.
2436		//
2437		// TODO(mdempsky): It should be safe to reshape them here too, but
2438		// maybe it's better to construct them with the proper type
2439		// instead.
2440		if x.Type() == types.UntypedBool && typ.IsBoolean() {
2441			return x
2442		}
2443
2444		base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
2445		base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
2446
2447		// We use ir.HasUniquePos here as a check that x only appears once
2448		// in the AST, so it's okay for us to call SetType without
2449		// breaking any other uses of it.
2450		//
2451		// Notably, any ONAMEs should already have the exactly right shape
2452		// type and been caught by types.IdenticalStrict above.
2453		base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
2454
2455		if base.Debug.Reshape != 0 {
2456			base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
2457		}
2458
2459		x.SetType(typ)
2460		return x
2461
2462	case exprConvert:
2463		implicit := r.Bool()
2464		typ := r.typ()
2465		pos := r.pos()
2466		typeWord, srcRType := r.convRTTI(pos)
2467		dstTypeParam := r.Bool()
2468		identical := r.Bool()
2469		x := r.expr()
2470
2471		// TODO(mdempsky): Stop constructing expressions of untyped type.
2472		x = typecheck.DefaultLit(x, typ)
2473
2474		ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
2475		ce.TypeWord, ce.SrcRType = typeWord, srcRType
2476		if implicit {
2477			ce.SetImplicit(true)
2478		}
2479		n := typecheck.Expr(ce)
2480
2481		// Conversions between non-identical, non-empty interfaces always
2482		// requires a runtime call, even if they have identical underlying
2483		// interfaces. This is because we create separate itab instances
2484		// for each unique interface type, not merely each unique
2485		// interface shape.
2486		//
2487		// However, due to shape types, typecheck.Expr might mistakenly
2488		// think a conversion between two non-empty interfaces are
2489		// identical and set ir.OCONVNOP, instead of ir.OCONVIFACE. To
2490		// ensure we update the itab field appropriately, we force it to
2491		// ir.OCONVIFACE instead when shape types are involved.
2492		//
2493		// TODO(mdempsky): Are there other places we might get this wrong?
2494		// Should this be moved down into typecheck.{Assign,Convert}op?
2495		// This would be a non-issue if itabs were unique for each
2496		// *underlying* interface type instead.
2497		if !identical {
2498			if n, ok := n.(*ir.ConvExpr); ok && n.Op() == ir.OCONVNOP && n.Type().IsInterface() && !n.Type().IsEmptyInterface() && (n.Type().HasShape() || n.X.Type().HasShape()) {
2499				n.SetOp(ir.OCONVIFACE)
2500			}
2501		}
2502
2503		// spec: "If the type is a type parameter, the constant is converted
2504		// into a non-constant value of the type parameter."
2505		if dstTypeParam && ir.IsConstNode(n) {
2506			// Wrap in an OCONVNOP node to ensure result is non-constant.
2507			n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
2508			n.SetTypecheck(1)
2509		}
2510		return n
2511
2512	case exprRuntimeBuiltin:
2513		builtin := typecheck.LookupRuntime(r.String())
2514		return builtin
2515	}
2516}
2517
2518// funcInst reads an instantiated function reference, and returns
2519// three (possibly nil) expressions related to it:
2520//
2521// baseFn is always non-nil: it's either a function of the appropriate
2522// type already, or it has an extra dictionary parameter as the first
2523// parameter.
2524//
2525// If dictPtr is non-nil, then it's a dictionary argument that must be
2526// passed as the first argument to baseFn.
2527//
2528// If wrapperFn is non-nil, then it's either the same as baseFn (if
2529// dictPtr is nil), or it's semantically equivalent to currying baseFn
2530// to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
2531// that needs to be computed dynamically.)
2532//
2533// For callers that are creating a call to the returned function, it's
2534// best to emit a call to baseFn, and include dictPtr in the arguments
2535// list as appropriate.
2536//
2537// For callers that want to return the function without invoking it,
2538// they may return wrapperFn if it's non-nil; but otherwise, they need
2539// to create their own wrapper.
2540func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) {
2541	// Like in methodExpr, I'm pretty sure this isn't needed.
2542	var implicits []*types.Type
2543	if r.dict != nil {
2544		implicits = r.dict.targs
2545	}
2546
2547	if r.Bool() { // dynamic subdictionary
2548		idx := r.Len()
2549		info := r.dict.subdicts[idx]
2550		explicits := r.p.typListIdx(info.explicits, r.dict)
2551
2552		baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
2553
2554		// TODO(mdempsky): Is there a more robust way to get the
2555		// dictionary pointer type here?
2556		dictPtrType := baseFn.Type().Param(0).Type
2557		dictPtr = typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
2558
2559		return
2560	}
2561
2562	info := r.objInfo()
2563	explicits := r.p.typListIdx(info.explicits, r.dict)
2564
2565	wrapperFn = r.p.objIdx(info.idx, implicits, explicits, false).(*ir.Name)
2566	baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
2567
2568	dictName := r.p.objDictName(info.idx, implicits, explicits)
2569	dictPtr = typecheck.Expr(ir.NewAddrExpr(pos, dictName))
2570
2571	return
2572}
2573
2574func (pr *pkgReader) objDictName(idx pkgbits.Index, implicits, explicits []*types.Type) *ir.Name {
2575	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
2576	_, sym := rname.qualifiedIdent()
2577	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
2578
2579	if tag == pkgbits.ObjStub {
2580		assert(!sym.IsBlank())
2581		if pri, ok := objReader[sym]; ok {
2582			return pri.pr.objDictName(pri.idx, nil, explicits)
2583		}
2584		base.Fatalf("unresolved stub: %v", sym)
2585	}
2586
2587	dict, err := pr.objDictIdx(sym, idx, implicits, explicits, false)
2588	if err != nil {
2589		base.Fatalf("%v", err)
2590	}
2591
2592	return pr.dictNameOf(dict)
2593}
2594
2595// curry returns a function literal that calls fun with arg0 and
2596// (optionally) arg1, accepting additional arguments to the function
2597// literal as necessary to satisfy fun's signature.
2598//
2599// If nilCheck is true and arg0 is an interface value, then it's
2600// checked to be non-nil as an initial step at the point of evaluating
2601// the function literal itself.
2602func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
2603	var captured ir.Nodes
2604	captured.Append(fun, arg0)
2605	if arg1 != nil {
2606		captured.Append(arg1)
2607	}
2608
2609	params, results := syntheticSig(fun.Type())
2610	params = params[len(captured)-1:] // skip curried parameters
2611	typ := types.NewSignature(nil, params, results)
2612
2613	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
2614		fun := captured[0]
2615
2616		var args ir.Nodes
2617		args.Append(captured[1:]...)
2618		args.Append(r.syntheticArgs()...)
2619
2620		r.syntheticTailCall(pos, fun, args)
2621	}
2622
2623	return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
2624}
2625
2626// methodExprWrap returns a function literal that changes method's
2627// first parameter's type to recv, and uses implicits/deref/addr to
2628// select the appropriate receiver parameter to pass to method.
2629func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
2630	var captured ir.Nodes
2631	captured.Append(method)
2632
2633	params, results := syntheticSig(method.Type())
2634
2635	// Change first parameter to recv.
2636	params[0].Type = recv
2637
2638	// If we have a dictionary pointer argument to pass, then omit the
2639	// underlying method expression's dictionary parameter from the
2640	// returned signature too.
2641	if dictPtr != nil {
2642		captured.Append(dictPtr)
2643		params = append(params[:1], params[2:]...)
2644	}
2645
2646	typ := types.NewSignature(nil, params, results)
2647
2648	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
2649		fn := captured[0]
2650		args := r.syntheticArgs()
2651
2652		// Rewrite first argument based on implicits/deref/addr.
2653		{
2654			arg := args[0]
2655			for _, ix := range implicits {
2656				arg = Implicit(typecheck.DotField(pos, arg, ix))
2657			}
2658			if deref {
2659				arg = Implicit(Deref(pos, arg.Type().Elem(), arg))
2660			} else if addr {
2661				arg = Implicit(Addr(pos, arg))
2662			}
2663			args[0] = arg
2664		}
2665
2666		// Insert dictionary argument, if provided.
2667		if dictPtr != nil {
2668			newArgs := make([]ir.Node, len(args)+1)
2669			newArgs[0] = args[0]
2670			newArgs[1] = captured[1]
2671			copy(newArgs[2:], args[1:])
2672			args = newArgs
2673		}
2674
2675		r.syntheticTailCall(pos, fn, args)
2676	}
2677
2678	return r.syntheticClosure(origPos, typ, false, captured, addBody)
2679}
2680
2681// syntheticClosure constructs a synthetic function literal for
2682// currying dictionary arguments. origPos is the position used for the
2683// closure, which must be a non-inlined position. typ is the function
2684// literal's signature type.
2685//
2686// captures is a list of expressions that need to be evaluated at the
2687// point of function literal evaluation and captured by the function
2688// literal. If ifaceHack is true and captures[1] is an interface type,
2689// it's checked to be non-nil after evaluation.
2690//
2691// addBody is a callback function to populate the function body. The
2692// list of captured values passed back has the captured variables for
2693// use within the function literal, corresponding to the expressions
2694// in captures.
2695func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
2696	// isSafe reports whether n is an expression that we can safely
2697	// defer to evaluating inside the closure instead, to avoid storing
2698	// them into the closure.
2699	//
2700	// In practice this is always (and only) the wrappee function.
2701	isSafe := func(n ir.Node) bool {
2702		if n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PFUNC {
2703			return true
2704		}
2705		if n.Op() == ir.OMETHEXPR {
2706			return true
2707		}
2708
2709		return false
2710	}
2711
2712	fn := r.inlClosureFunc(origPos, typ, ir.OCLOSURE)
2713	fn.SetWrapper(true)
2714
2715	clo := fn.OClosure
2716	inlPos := clo.Pos()
2717
2718	var init ir.Nodes
2719	for i, n := range captures {
2720		if isSafe(n) {
2721			continue // skip capture; can reference directly
2722		}
2723
2724		tmp := r.tempCopy(inlPos, n, &init)
2725		ir.NewClosureVar(origPos, fn, tmp)
2726
2727		// We need to nil check interface receivers at the point of method
2728		// value evaluation, ugh.
2729		if ifaceHack && i == 1 && n.Type().IsInterface() {
2730			check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
2731			init.Append(typecheck.Stmt(check))
2732		}
2733	}
2734
2735	pri := pkgReaderIndex{synthetic: func(pos src.XPos, r *reader) {
2736		captured := make([]ir.Node, len(captures))
2737		next := 0
2738		for i, n := range captures {
2739			if isSafe(n) {
2740				captured[i] = n
2741			} else {
2742				captured[i] = r.closureVars[next]
2743				next++
2744			}
2745		}
2746		assert(next == len(r.closureVars))
2747
2748		addBody(origPos, r, captured)
2749	}}
2750	bodyReader[fn] = pri
2751	pri.funcBody(fn)
2752
2753	return ir.InitExpr(init, clo)
2754}
2755
2756// syntheticSig duplicates and returns the params and results lists
2757// for sig, but renaming anonymous parameters so they can be assigned
2758// ir.Names.
2759func syntheticSig(sig *types.Type) (params, results []*types.Field) {
2760	clone := func(params []*types.Field) []*types.Field {
2761		res := make([]*types.Field, len(params))
2762		for i, param := range params {
2763			// TODO(mdempsky): It would be nice to preserve the original
2764			// parameter positions here instead, but at least
2765			// typecheck.NewMethodType replaces them with base.Pos, making
2766			// them useless. Worse, the positions copied from base.Pos may
2767			// have inlining contexts, which we definitely don't want here
2768			// (e.g., #54625).
2769			res[i] = types.NewField(base.AutogeneratedPos, param.Sym, param.Type)
2770			res[i].SetIsDDD(param.IsDDD())
2771		}
2772		return res
2773	}
2774
2775	return clone(sig.Params()), clone(sig.Results())
2776}
2777
2778func (r *reader) optExpr() ir.Node {
2779	if r.Bool() {
2780		return r.expr()
2781	}
2782	return nil
2783}
2784
2785// methodExpr reads a method expression reference, and returns three
2786// (possibly nil) expressions related to it:
2787//
2788// baseFn is always non-nil: it's either a function of the appropriate
2789// type already, or it has an extra dictionary parameter as the second
2790// parameter (i.e., immediately after the promoted receiver
2791// parameter).
2792//
2793// If dictPtr is non-nil, then it's a dictionary argument that must be
2794// passed as the second argument to baseFn.
2795//
2796// If wrapperFn is non-nil, then it's either the same as baseFn (if
2797// dictPtr is nil), or it's semantically equivalent to currying baseFn
2798// to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
2799// that needs to be computed dynamically.)
2800//
2801// For callers that are creating a call to the returned method, it's
2802// best to emit a call to baseFn, and include dictPtr in the arguments
2803// list as appropriate.
2804//
2805// For callers that want to return a method expression without
2806// invoking it, they may return wrapperFn if it's non-nil; but
2807// otherwise, they need to create their own wrapper.
2808func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) {
2809	recv := r.typ()
2810	sig0 := r.typ()
2811	pos := r.pos()
2812	sym := r.selector()
2813
2814	// Signature type to return (i.e., recv prepended to the method's
2815	// normal parameters list).
2816	sig := typecheck.NewMethodType(sig0, recv)
2817
2818	if r.Bool() { // type parameter method expression
2819		idx := r.Len()
2820		word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx)
2821
2822		// TODO(mdempsky): If the type parameter was instantiated with an
2823		// interface type (i.e., embed.IsInterface()), then we could
2824		// return the OMETHEXPR instead and save an indirection.
2825
2826		// We wrote the method expression's entry point PC into the
2827		// dictionary, but for Go `func` values we need to return a
2828		// closure (i.e., pointer to a structure with the PC as the first
2829		// field). Because method expressions don't have any closure
2830		// variables, we pun the dictionary entry as the closure struct.
2831		fn := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, sig, ir.NewAddrExpr(pos, word)))
2832		return fn, fn, nil
2833	}
2834
2835	// TODO(mdempsky): I'm pretty sure this isn't needed: implicits is
2836	// only relevant to locally defined types, but they can't have
2837	// (non-promoted) methods.
2838	var implicits []*types.Type
2839	if r.dict != nil {
2840		implicits = r.dict.targs
2841	}
2842
2843	if r.Bool() { // dynamic subdictionary
2844		idx := r.Len()
2845		info := r.dict.subdicts[idx]
2846		explicits := r.p.typListIdx(info.explicits, r.dict)
2847
2848		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
2849		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
2850
2851		// TODO(mdempsky): Is there a more robust way to get the
2852		// dictionary pointer type here?
2853		dictPtrType := shapedFn.Type().Param(1).Type
2854		dictPtr := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
2855
2856		return nil, shapedFn, dictPtr
2857	}
2858
2859	if r.Bool() { // static dictionary
2860		info := r.objInfo()
2861		explicits := r.p.typListIdx(info.explicits, r.dict)
2862
2863		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
2864		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
2865
2866		dict := r.p.objDictName(info.idx, implicits, explicits)
2867		dictPtr := typecheck.Expr(ir.NewAddrExpr(pos, dict))
2868
2869		// Check that dictPtr matches shapedFn's dictionary parameter.
2870		if !types.Identical(dictPtr.Type(), shapedFn.Type().Param(1).Type) {
2871			base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn)
2872		}
2873
2874		// For statically known instantiations, we can take advantage of
2875		// the stenciled wrapper.
2876		base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv)
2877		wrapperFn := typecheck.NewMethodExpr(pos, recv, sym)
2878		base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig)
2879
2880		return wrapperFn, shapedFn, dictPtr
2881	}
2882
2883	// Simple method expression; no dictionary needed.
2884	base.AssertfAt(!recv.HasShape() || recv.IsInterface(), pos, "shaped receiver %v", recv)
2885	fn := typecheck.NewMethodExpr(pos, recv, sym)
2886	return fn, fn, nil
2887}
2888
2889// shapedMethodExpr returns the specified method on the given shaped
2890// type.
2891func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) *ir.SelectorExpr {
2892	assert(obj.Op() == ir.OTYPE)
2893
2894	typ := obj.Type()
2895	assert(typ.HasShape())
2896
2897	method := func() *types.Field {
2898		for _, method := range typ.Methods() {
2899			if method.Sym == sym {
2900				return method
2901			}
2902		}
2903
2904		base.FatalfAt(pos, "failed to find method %v in shaped type %v", sym, typ)
2905		panic("unreachable")
2906	}()
2907
2908	// Construct an OMETHEXPR node.
2909	recv := method.Type.Recv().Type
2910	return typecheck.NewMethodExpr(pos, recv, sym)
2911}
2912
2913func (r *reader) multiExpr() []ir.Node {
2914	r.Sync(pkgbits.SyncMultiExpr)
2915
2916	if r.Bool() { // N:1
2917		pos := r.pos()
2918		expr := r.expr()
2919
2920		results := make([]ir.Node, r.Len())
2921		as := ir.NewAssignListStmt(pos, ir.OAS2, nil, []ir.Node{expr})
2922		as.Def = true
2923		for i := range results {
2924			tmp := r.temp(pos, r.typ())
2925			as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
2926			as.Lhs.Append(tmp)
2927
2928			res := ir.Node(tmp)
2929			if r.Bool() {
2930				n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
2931				n.TypeWord, n.SrcRType = r.convRTTI(pos)
2932				n.SetImplicit(true)
2933				res = typecheck.Expr(n)
2934			}
2935			results[i] = res
2936		}
2937
2938		// TODO(mdempsky): Could use ir.InlinedCallExpr instead?
2939		results[0] = ir.InitExpr([]ir.Node{typecheck.Stmt(as)}, results[0])
2940		return results
2941	}
2942
2943	// N:N
2944	exprs := make([]ir.Node, r.Len())
2945	if len(exprs) == 0 {
2946		return nil
2947	}
2948	for i := range exprs {
2949		exprs[i] = r.expr()
2950	}
2951	return exprs
2952}
2953
2954// temp returns a new autotemp of the specified type.
2955func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
2956	return typecheck.TempAt(pos, r.curfn, typ)
2957}
2958
2959// tempCopy declares and returns a new autotemp initialized to the
2960// value of expr.
2961func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
2962	tmp := r.temp(pos, expr.Type())
2963
2964	init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
2965
2966	assign := ir.NewAssignStmt(pos, tmp, expr)
2967	assign.Def = true
2968	init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, tmp, expr)))
2969
2970	tmp.Defn = assign
2971
2972	return tmp
2973}
2974
2975func (r *reader) compLit() ir.Node {
2976	r.Sync(pkgbits.SyncCompLit)
2977	pos := r.pos()
2978	typ0 := r.typ()
2979
2980	typ := typ0
2981	if typ.IsPtr() {
2982		typ = typ.Elem()
2983	}
2984	if typ.Kind() == types.TFORW {
2985		base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
2986	}
2987	var rtype ir.Node
2988	if typ.IsMap() {
2989		rtype = r.rtype(pos)
2990	}
2991	isStruct := typ.Kind() == types.TSTRUCT
2992
2993	elems := make([]ir.Node, r.Len())
2994	for i := range elems {
2995		elemp := &elems[i]
2996
2997		if isStruct {
2998			sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil)
2999			*elemp, elemp = sk, &sk.Value
3000		} else if r.Bool() {
3001			kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
3002			*elemp, elemp = kv, &kv.Value
3003		}
3004
3005		*elemp = r.expr()
3006	}
3007
3008	lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
3009	if rtype != nil {
3010		lit := lit.(*ir.CompLitExpr)
3011		lit.RType = rtype
3012	}
3013	if typ0.IsPtr() {
3014		lit = typecheck.Expr(typecheck.NodAddrAt(pos, lit))
3015		lit.SetType(typ0)
3016	}
3017	return lit
3018}
3019
3020func (r *reader) funcLit() ir.Node {
3021	r.Sync(pkgbits.SyncFuncLit)
3022
3023	// The underlying function declaration (including its parameters'
3024	// positions, if any) need to remain the original, uninlined
3025	// positions. This is because we track inlining-context on nodes so
3026	// we can synthesize the extra implied stack frames dynamically when
3027	// generating tracebacks, whereas those stack frames don't make
3028	// sense *within* the function literal. (Any necessary inlining
3029	// adjustments will have been applied to the call expression
3030	// instead.)
3031	//
3032	// This is subtle, and getting it wrong leads to cycles in the
3033	// inlining tree, which lead to infinite loops during stack
3034	// unwinding (#46234, #54625).
3035	//
3036	// Note that we *do* want the inline-adjusted position for the
3037	// OCLOSURE node, because that position represents where any heap
3038	// allocation of the closure is credited (#49171).
3039	r.suppressInlPos++
3040	origPos := r.pos()
3041	sig := r.signature(nil)
3042	r.suppressInlPos--
3043	why := ir.OCLOSURE
3044	if r.Bool() {
3045		why = ir.ORANGE
3046	}
3047
3048	fn := r.inlClosureFunc(origPos, sig, why)
3049
3050	fn.ClosureVars = make([]*ir.Name, 0, r.Len())
3051	for len(fn.ClosureVars) < cap(fn.ClosureVars) {
3052		// TODO(mdempsky): I think these should be original positions too
3053		// (i.e., not inline-adjusted).
3054		ir.NewClosureVar(r.pos(), fn, r.useLocal())
3055	}
3056	if param := r.dictParam; param != nil {
3057		// If we have a dictionary parameter, capture it too. For
3058		// simplicity, we capture it last and unconditionally.
3059		ir.NewClosureVar(param.Pos(), fn, param)
3060	}
3061
3062	r.addBody(fn, nil)
3063
3064	// un-hide closures belong to init function.
3065	if (r.curfn.IsPackageInit() || strings.HasPrefix(r.curfn.Sym().Name, "init.")) && ir.IsTrivialClosure(fn.OClosure) {
3066		fn.SetIsHiddenClosure(false)
3067	}
3068
3069	return fn.OClosure
3070}
3071
3072// inlClosureFunc constructs a new closure function, but correctly
3073// handles inlining.
3074func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *ir.Func {
3075	curfn := r.inlCaller
3076	if curfn == nil {
3077		curfn = r.curfn
3078	}
3079
3080	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
3081	return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target)
3082}
3083
3084func (r *reader) exprList() []ir.Node {
3085	r.Sync(pkgbits.SyncExprList)
3086	return r.exprs()
3087}
3088
3089func (r *reader) exprs() []ir.Node {
3090	r.Sync(pkgbits.SyncExprs)
3091	nodes := make([]ir.Node, r.Len())
3092	if len(nodes) == 0 {
3093		return nil // TODO(mdempsky): Unclear if this matters.
3094	}
3095	for i := range nodes {
3096		nodes[i] = r.expr()
3097	}
3098	return nodes
3099}
3100
3101// dictWord returns an expression to return the specified
3102// uintptr-typed word from the dictionary parameter.
3103func (r *reader) dictWord(pos src.XPos, idx int) ir.Node {
3104	base.AssertfAt(r.dictParam != nil, pos, "expected dictParam in %v", r.curfn)
3105	return typecheck.Expr(ir.NewIndexExpr(pos, r.dictParam, ir.NewInt(pos, int64(idx))))
3106}
3107
3108// rttiWord is like dictWord, but converts it to *byte (the type used
3109// internally to represent *runtime._type and *runtime.itab).
3110func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node {
3111	return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TUINT8]), r.dictWord(pos, idx)))
3112}
3113
3114// rtype reads a type reference from the element bitstream, and
3115// returns an expression of type *runtime._type representing that
3116// type.
3117func (r *reader) rtype(pos src.XPos) ir.Node {
3118	_, rtype := r.rtype0(pos)
3119	return rtype
3120}
3121
3122func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
3123	r.Sync(pkgbits.SyncRType)
3124	if r.Bool() { // derived type
3125		idx := r.Len()
3126		info := r.dict.rtypes[idx]
3127		typ = r.p.typIdx(info, r.dict, true)
3128		rtype = r.rttiWord(pos, r.dict.rtypesOffset()+idx)
3129		return
3130	}
3131
3132	typ = r.typ()
3133	rtype = reflectdata.TypePtrAt(pos, typ)
3134	return
3135}
3136
3137// varDictIndex populates name.DictIndex if name is a derived type.
3138func (r *reader) varDictIndex(name *ir.Name) {
3139	if r.Bool() {
3140		idx := 1 + r.dict.rtypesOffset() + r.Len()
3141		if int(uint16(idx)) != idx {
3142			base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
3143		}
3144		name.DictIndex = uint16(idx)
3145	}
3146}
3147
3148// itab returns a (typ, iface) pair of types.
3149//
3150// typRType and ifaceRType are expressions that evaluate to the
3151// *runtime._type for typ and iface, respectively.
3152//
3153// If typ is a concrete type and iface is a non-empty interface type,
3154// then itab is an expression that evaluates to the *runtime.itab for
3155// the pair. Otherwise, itab is nil.
3156func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
3157	typ, typRType = r.rtype0(pos)
3158	iface, ifaceRType = r.rtype0(pos)
3159
3160	idx := -1
3161	if r.Bool() {
3162		idx = r.Len()
3163	}
3164
3165	if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
3166		if idx >= 0 {
3167			itab = r.rttiWord(pos, r.dict.itabsOffset()+idx)
3168		} else {
3169			base.AssertfAt(!typ.HasShape(), pos, "%v is a shape type", typ)
3170			base.AssertfAt(!iface.HasShape(), pos, "%v is a shape type", iface)
3171
3172			lsym := reflectdata.ITabLsym(typ, iface)
3173			itab = typecheck.LinksymAddr(pos, lsym, types.Types[types.TUINT8])
3174		}
3175	}
3176
3177	return
3178}
3179
3180// convRTTI returns expressions appropriate for populating an
3181// ir.ConvExpr's TypeWord and SrcRType fields, respectively.
3182func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
3183	r.Sync(pkgbits.SyncConvRTTI)
3184	src, srcRType0, dst, dstRType, itab := r.itab(pos)
3185	if !dst.IsInterface() {
3186		return
3187	}
3188
3189	// See reflectdata.ConvIfaceTypeWord.
3190	switch {
3191	case dst.IsEmptyInterface():
3192		if !src.IsInterface() {
3193			typeWord = srcRType0 // direct eface construction
3194		}
3195	case !src.IsInterface():
3196		typeWord = itab // direct iface construction
3197	default:
3198		typeWord = dstRType // convI2I
3199	}
3200
3201	// See reflectdata.ConvIfaceSrcRType.
3202	if !src.IsInterface() {
3203		srcRType = srcRType0
3204	}
3205
3206	return
3207}
3208
3209func (r *reader) exprType() ir.Node {
3210	r.Sync(pkgbits.SyncExprType)
3211	pos := r.pos()
3212
3213	var typ *types.Type
3214	var rtype, itab ir.Node
3215
3216	if r.Bool() {
3217		typ, rtype, _, _, itab = r.itab(pos)
3218		if !typ.IsInterface() {
3219			rtype = nil // TODO(mdempsky): Leave set?
3220		}
3221	} else {
3222		typ, rtype = r.rtype0(pos)
3223
3224		if !r.Bool() { // not derived
3225			return ir.TypeNode(typ)
3226		}
3227	}
3228
3229	dt := ir.NewDynamicType(pos, rtype)
3230	dt.ITab = itab
3231	return typed(typ, dt)
3232}
3233
3234func (r *reader) op() ir.Op {
3235	r.Sync(pkgbits.SyncOp)
3236	return ir.Op(r.Len())
3237}
3238
3239// @@@ Package initialization
3240
3241func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
3242	cgoPragmas := make([][]string, r.Len())
3243	for i := range cgoPragmas {
3244		cgoPragmas[i] = r.Strings()
3245	}
3246	target.CgoPragmas = cgoPragmas
3247
3248	r.pkgInitOrder(target)
3249
3250	r.pkgDecls(target)
3251
3252	r.Sync(pkgbits.SyncEOF)
3253}
3254
3255// pkgInitOrder creates a synthetic init function to handle any
3256// package-scope initialization statements.
3257func (r *reader) pkgInitOrder(target *ir.Package) {
3258	initOrder := make([]ir.Node, r.Len())
3259	if len(initOrder) == 0 {
3260		return
3261	}
3262
3263	// Make a function that contains all the initialization statements.
3264	pos := base.AutogeneratedPos
3265	base.Pos = pos
3266
3267	fn := ir.NewFunc(pos, pos, typecheck.Lookup("init"), types.NewSignature(nil, nil, nil))
3268	fn.SetIsPackageInit(true)
3269	fn.SetInlinabilityChecked(true) // suppress useless "can inline" diagnostics
3270
3271	typecheck.DeclFunc(fn)
3272	r.curfn = fn
3273
3274	for i := range initOrder {
3275		lhs := make([]ir.Node, r.Len())
3276		for j := range lhs {
3277			lhs[j] = r.obj()
3278		}
3279		rhs := r.expr()
3280		pos := lhs[0].Pos()
3281
3282		var as ir.Node
3283		if len(lhs) == 1 {
3284			as = typecheck.Stmt(ir.NewAssignStmt(pos, lhs[0], rhs))
3285		} else {
3286			as = typecheck.Stmt(ir.NewAssignListStmt(pos, ir.OAS2, lhs, []ir.Node{rhs}))
3287		}
3288
3289		for _, v := range lhs {
3290			v.(*ir.Name).Defn = as
3291		}
3292
3293		initOrder[i] = as
3294	}
3295
3296	fn.Body = initOrder
3297
3298	typecheck.FinishFuncBody()
3299	r.curfn = nil
3300	r.locals = nil
3301
3302	// Outline (if legal/profitable) global map inits.
3303	staticinit.OutlineMapInits(fn)
3304
3305	target.Inits = append(target.Inits, fn)
3306}
3307
3308func (r *reader) pkgDecls(target *ir.Package) {
3309	r.Sync(pkgbits.SyncDecls)
3310	for {
3311		switch code := codeDecl(r.Code(pkgbits.SyncDecl)); code {
3312		default:
3313			panic(fmt.Sprintf("unhandled decl: %v", code))
3314
3315		case declEnd:
3316			return
3317
3318		case declFunc:
3319			names := r.pkgObjs(target)
3320			assert(len(names) == 1)
3321			target.Funcs = append(target.Funcs, names[0].Func)
3322
3323		case declMethod:
3324			typ := r.typ()
3325			sym := r.selector()
3326
3327			method := typecheck.Lookdot1(nil, sym, typ, typ.Methods(), 0)
3328			target.Funcs = append(target.Funcs, method.Nname.(*ir.Name).Func)
3329
3330		case declVar:
3331			names := r.pkgObjs(target)
3332
3333			if n := r.Len(); n > 0 {
3334				assert(len(names) == 1)
3335				embeds := make([]ir.Embed, n)
3336				for i := range embeds {
3337					embeds[i] = ir.Embed{Pos: r.pos(), Patterns: r.Strings()}
3338				}
3339				names[0].Embed = &embeds
3340				target.Embeds = append(target.Embeds, names[0])
3341			}
3342
3343		case declOther:
3344			r.pkgObjs(target)
3345		}
3346	}
3347}
3348
3349func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
3350	r.Sync(pkgbits.SyncDeclNames)
3351	nodes := make([]*ir.Name, r.Len())
3352	for i := range nodes {
3353		r.Sync(pkgbits.SyncDeclName)
3354
3355		name := r.obj().(*ir.Name)
3356		nodes[i] = name
3357
3358		sym := name.Sym()
3359		if sym.IsBlank() {
3360			continue
3361		}
3362
3363		switch name.Class {
3364		default:
3365			base.FatalfAt(name.Pos(), "unexpected class: %v", name.Class)
3366
3367		case ir.PEXTERN:
3368			target.Externs = append(target.Externs, name)
3369
3370		case ir.PFUNC:
3371			assert(name.Type().Recv() == nil)
3372
3373			// TODO(mdempsky): Cleaner way to recognize init?
3374			if strings.HasPrefix(sym.Name, "init.") {
3375				target.Inits = append(target.Inits, name.Func)
3376			}
3377		}
3378
3379		if base.Ctxt.Flag_dynlink && types.LocalPkg.Name == "main" && types.IsExported(sym.Name) && name.Op() == ir.ONAME {
3380			assert(!sym.OnExportList())
3381			target.PluginExports = append(target.PluginExports, name)
3382			sym.SetOnExportList(true)
3383		}
3384
3385		if base.Flag.AsmHdr != "" && (name.Op() == ir.OLITERAL || name.Op() == ir.OTYPE) {
3386			assert(!sym.Asm())
3387			target.AsmHdrDecls = append(target.AsmHdrDecls, name)
3388			sym.SetAsm(true)
3389		}
3390	}
3391
3392	return nodes
3393}
3394
3395// @@@ Inlining
3396
3397// unifiedHaveInlineBody reports whether we have the function body for
3398// fn, so we can inline it.
3399func unifiedHaveInlineBody(fn *ir.Func) bool {
3400	if fn.Inl == nil {
3401		return false
3402	}
3403
3404	_, ok := bodyReaderFor(fn)
3405	return ok
3406}
3407
3408var inlgen = 0
3409
3410// unifiedInlineCall implements inline.NewInline by re-reading the function
3411// body from its Unified IR export data.
3412func unifiedInlineCall(callerfn *ir.Func, call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
3413	pri, ok := bodyReaderFor(fn)
3414	if !ok {
3415		base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
3416	}
3417
3418	if !fn.Inl.HaveDcl {
3419		expandInline(fn, pri)
3420	}
3421
3422	r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
3423
3424	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type())
3425
3426	r.curfn = tmpfn
3427
3428	r.inlCaller = callerfn
3429	r.inlCall = call
3430	r.inlFunc = fn
3431	r.inlTreeIndex = inlIndex
3432	r.inlPosBases = make(map[*src.PosBase]*src.PosBase)
3433	r.funarghack = true
3434
3435	r.closureVars = make([]*ir.Name, len(r.inlFunc.ClosureVars))
3436	for i, cv := range r.inlFunc.ClosureVars {
3437		// TODO(mdempsky): It should be possible to support this case, but
3438		// for now we rely on the inliner avoiding it.
3439		if cv.Outer.Curfn != callerfn {
3440			base.FatalfAt(call.Pos(), "inlining closure call across frames")
3441		}
3442		r.closureVars[i] = cv.Outer
3443	}
3444	if len(r.closureVars) != 0 && r.hasTypeParams() {
3445		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
3446	}
3447
3448	r.declareParams()
3449
3450	var inlvars, retvars []*ir.Name
3451	{
3452		sig := r.curfn.Type()
3453		endParams := sig.NumRecvs() + sig.NumParams()
3454		endResults := endParams + sig.NumResults()
3455
3456		inlvars = r.curfn.Dcl[:endParams]
3457		retvars = r.curfn.Dcl[endParams:endResults]
3458	}
3459
3460	r.delayResults = fn.Inl.CanDelayResults
3461
3462	r.retlabel = typecheck.AutoLabel(".i")
3463	inlgen++
3464
3465	init := ir.TakeInit(call)
3466
3467	// For normal function calls, the function callee expression
3468	// may contain side effects. Make sure to preserve these,
3469	// if necessary (#42703).
3470	if call.Op() == ir.OCALLFUNC {
3471		inline.CalleeEffects(&init, call.Fun)
3472	}
3473
3474	var args ir.Nodes
3475	if call.Op() == ir.OCALLMETH {
3476		base.FatalfAt(call.Pos(), "OCALLMETH missed by typecheck")
3477	}
3478	args.Append(call.Args...)
3479
3480	// Create assignment to declare and initialize inlvars.
3481	as2 := ir.NewAssignListStmt(call.Pos(), ir.OAS2, ir.ToNodes(inlvars), args)
3482	as2.Def = true
3483	var as2init ir.Nodes
3484	for _, name := range inlvars {
3485		if ir.IsBlank(name) {
3486			continue
3487		}
3488		// TODO(mdempsky): Use inlined position of name.Pos() instead?
3489		as2init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
3490		name.Defn = as2
3491	}
3492	as2.SetInit(as2init)
3493	init.Append(typecheck.Stmt(as2))
3494
3495	if !r.delayResults {
3496		// If not delaying retvars, declare and zero initialize the
3497		// result variables now.
3498		for _, name := range retvars {
3499			// TODO(mdempsky): Use inlined position of name.Pos() instead?
3500			init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
3501			ras := ir.NewAssignStmt(call.Pos(), name, nil)
3502			init.Append(typecheck.Stmt(ras))
3503		}
3504	}
3505
3506	// Add an inline mark just before the inlined body.
3507	// This mark is inline in the code so that it's a reasonable spot
3508	// to put a breakpoint. Not sure if that's really necessary or not
3509	// (in which case it could go at the end of the function instead).
3510	// Note issue 28603.
3511	init.Append(ir.NewInlineMarkStmt(call.Pos().WithIsStmt(), int64(r.inlTreeIndex)))
3512
3513	ir.WithFunc(r.curfn, func() {
3514		if !r.syntheticBody(call.Pos()) {
3515			assert(r.Bool()) // have body
3516
3517			r.curfn.Body = r.stmts()
3518			r.curfn.Endlineno = r.pos()
3519		}
3520
3521		// TODO(mdempsky): This shouldn't be necessary. Inlining might
3522		// read in new function/method declarations, which could
3523		// potentially be recursively inlined themselves; but we shouldn't
3524		// need to read in the non-inlined bodies for the declarations
3525		// themselves. But currently it's an easy fix to #50552.
3526		readBodies(typecheck.Target, true)
3527
3528		// Replace any "return" statements within the function body.
3529		var edit func(ir.Node) ir.Node
3530		edit = func(n ir.Node) ir.Node {
3531			if ret, ok := n.(*ir.ReturnStmt); ok {
3532				n = typecheck.Stmt(r.inlReturn(ret, retvars))
3533			}
3534			ir.EditChildren(n, edit)
3535			return n
3536		}
3537		edit(r.curfn)
3538	})
3539
3540	body := ir.Nodes(r.curfn.Body)
3541
3542	// Reparent any declarations into the caller function.
3543	for _, name := range r.curfn.Dcl {
3544		name.Curfn = callerfn
3545
3546		if name.Class != ir.PAUTO {
3547			name.SetPos(r.inlPos(name.Pos()))
3548			name.SetInlFormal(true)
3549			name.Class = ir.PAUTO
3550		} else {
3551			name.SetInlLocal(true)
3552		}
3553	}
3554	callerfn.Dcl = append(callerfn.Dcl, r.curfn.Dcl...)
3555
3556	body.Append(ir.NewLabelStmt(call.Pos(), r.retlabel))
3557
3558	res := ir.NewInlinedCallExpr(call.Pos(), body, ir.ToNodes(retvars))
3559	res.SetInit(init)
3560	res.SetType(call.Type())
3561	res.SetTypecheck(1)
3562
3563	// Inlining shouldn't add any functions to todoBodies.
3564	assert(len(todoBodies) == 0)
3565
3566	return res
3567}
3568
3569// inlReturn returns a statement that can substitute for the given
3570// return statement when inlining.
3571func (r *reader) inlReturn(ret *ir.ReturnStmt, retvars []*ir.Name) *ir.BlockStmt {
3572	pos := r.inlCall.Pos()
3573
3574	block := ir.TakeInit(ret)
3575
3576	if results := ret.Results; len(results) != 0 {
3577		assert(len(retvars) == len(results))
3578
3579		as2 := ir.NewAssignListStmt(pos, ir.OAS2, ir.ToNodes(retvars), ret.Results)
3580
3581		if r.delayResults {
3582			for _, name := range retvars {
3583				// TODO(mdempsky): Use inlined position of name.Pos() instead?
3584				block.Append(ir.NewDecl(pos, ir.ODCL, name))
3585				name.Defn = as2
3586			}
3587		}
3588
3589		block.Append(as2)
3590	}
3591
3592	block.Append(ir.NewBranchStmt(pos, ir.OGOTO, r.retlabel))
3593	return ir.NewBlockStmt(pos, block)
3594}
3595
3596// expandInline reads in an extra copy of IR to populate
3597// fn.Inl.Dcl.
3598func expandInline(fn *ir.Func, pri pkgReaderIndex) {
3599	// TODO(mdempsky): Remove this function. It's currently needed by
3600	// dwarfgen/dwarf.go:preInliningDcls, which requires fn.Inl.Dcl to
3601	// create abstract function DIEs. But we should be able to provide it
3602	// with the same information some other way.
3603
3604	fndcls := len(fn.Dcl)
3605	topdcls := len(typecheck.Target.Funcs)
3606
3607	tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), fn.Sym(), fn.Type())
3608	tmpfn.ClosureVars = fn.ClosureVars
3609
3610	{
3611		r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
3612
3613		// Don't change parameter's Sym/Nname fields.
3614		r.funarghack = true
3615
3616		r.funcBody(tmpfn)
3617	}
3618
3619	// Move tmpfn's params to fn.Inl.Dcl, and reparent under fn.
3620	for _, name := range tmpfn.Dcl {
3621		name.Curfn = fn
3622	}
3623	fn.Inl.Dcl = tmpfn.Dcl
3624	fn.Inl.HaveDcl = true
3625
3626	// Double check that we didn't change fn.Dcl by accident.
3627	assert(fndcls == len(fn.Dcl))
3628
3629	// typecheck.Stmts may have added function literals to
3630	// typecheck.Target.Decls. Remove them again so we don't risk trying
3631	// to compile them multiple times.
3632	typecheck.Target.Funcs = typecheck.Target.Funcs[:topdcls]
3633}
3634
3635// usedLocals returns a set of local variables that are used within body.
3636func usedLocals(body []ir.Node) ir.NameSet {
3637	var used ir.NameSet
3638	ir.VisitList(body, func(n ir.Node) {
3639		if n, ok := n.(*ir.Name); ok && n.Op() == ir.ONAME && n.Class == ir.PAUTO {
3640			used.Add(n)
3641		}
3642	})
3643	return used
3644}
3645
3646// @@@ Method wrappers
3647//
3648// Here we handle constructing "method wrappers," alternative entry
3649// points that adapt methods to different calling conventions. Given a
3650// user-declared method "func (T) M(i int) bool { ... }", there are a
3651// few wrappers we may need to construct:
3652//
3653//	- Implicit dereferencing. Methods declared with a value receiver T
3654//	  are also included in the method set of the pointer type *T, so
3655//	  we need to construct a wrapper like "func (recv *T) M(i int)
3656//	  bool { return (*recv).M(i) }".
3657//
3658//	- Promoted methods. If struct type U contains an embedded field of
3659//	  type T or *T, we need to construct a wrapper like "func (recv U)
3660//	  M(i int) bool { return recv.T.M(i) }".
3661//
3662//	- Method values. If x is an expression of type T, then "x.M" is
3663//	  roughly "tmp := x; func(i int) bool { return tmp.M(i) }".
3664//
3665// At call sites, we always prefer to call the user-declared method
3666// directly, if known, so wrappers are only needed for indirect calls
3667// (for example, interface method calls that can't be devirtualized).
3668// Consequently, we can save some compile time by skipping
3669// construction of wrappers that are never needed.
3670//
3671// Alternatively, because the linker doesn't care which compilation
3672// unit constructed a particular wrapper, we can instead construct
3673// them as needed. However, if a wrapper is needed in multiple
3674// downstream packages, we may end up needing to compile it multiple
3675// times, costing us more compile time and object file size. (We mark
3676// the wrappers as DUPOK, so the linker doesn't complain about the
3677// duplicate symbols.)
3678//
3679// The current heuristics we use to balance these trade offs are:
3680//
3681//	- For a (non-parameterized) defined type T, we construct wrappers
3682//	  for *T and any promoted methods on T (and *T) in the same
3683//	  compilation unit as the type declaration.
3684//
3685//	- For a parameterized defined type, we construct wrappers in the
3686//	  compilation units in which the type is instantiated. We
3687//	  similarly handle wrappers for anonymous types with methods and
3688//	  compilation units where their type literals appear in source.
3689//
3690//	- Method value expressions are relatively uncommon, so we
3691//	  construct their wrappers in the compilation units that they
3692//	  appear in.
3693//
3694// Finally, as an opportunistic compile-time optimization, if we know
3695// a wrapper was constructed in any imported package's compilation
3696// unit, then we skip constructing a duplicate one. However, currently
3697// this is only done on a best-effort basis.
3698
3699// needWrapperTypes lists types for which we may need to generate
3700// method wrappers.
3701var needWrapperTypes []*types.Type
3702
3703// haveWrapperTypes lists types for which we know we already have
3704// method wrappers, because we found the type in an imported package.
3705var haveWrapperTypes []*types.Type
3706
3707// needMethodValueWrappers lists methods for which we may need to
3708// generate method value wrappers.
3709var needMethodValueWrappers []methodValueWrapper
3710
3711// haveMethodValueWrappers lists methods for which we know we already
3712// have method value wrappers, because we found it in an imported
3713// package.
3714var haveMethodValueWrappers []methodValueWrapper
3715
3716type methodValueWrapper struct {
3717	rcvr   *types.Type
3718	method *types.Field
3719}
3720
3721// needWrapper records that wrapper methods may be needed at link
3722// time.
3723func (r *reader) needWrapper(typ *types.Type) {
3724	if typ.IsPtr() {
3725		return
3726	}
3727
3728	// Special case: runtime must define error even if imported packages mention it (#29304).
3729	forceNeed := typ == types.ErrorType && base.Ctxt.Pkgpath == "runtime"
3730
3731	// If a type was found in an imported package, then we can assume
3732	// that package (or one of its transitive dependencies) already
3733	// generated method wrappers for it.
3734	if r.importedDef() && !forceNeed {
3735		haveWrapperTypes = append(haveWrapperTypes, typ)
3736	} else {
3737		needWrapperTypes = append(needWrapperTypes, typ)
3738	}
3739}
3740
3741// importedDef reports whether r is reading from an imported and
3742// non-generic element.
3743//
3744// If a type was found in an imported package, then we can assume that
3745// package (or one of its transitive dependencies) already generated
3746// method wrappers for it.
3747//
3748// Exception: If we're instantiating an imported generic type or
3749// function, we might be instantiating it with type arguments not
3750// previously seen before.
3751//
3752// TODO(mdempsky): Distinguish when a generic function or type was
3753// instantiated in an imported package so that we can add types to
3754// haveWrapperTypes instead.
3755func (r *reader) importedDef() bool {
3756	return r.p != localPkgReader && !r.hasTypeParams()
3757}
3758
3759// MakeWrappers constructs all wrapper methods needed for the target
3760// compilation unit.
3761func MakeWrappers(target *ir.Package) {
3762	// always generate a wrapper for error.Error (#29304)
3763	needWrapperTypes = append(needWrapperTypes, types.ErrorType)
3764
3765	seen := make(map[string]*types.Type)
3766
3767	for _, typ := range haveWrapperTypes {
3768		wrapType(typ, target, seen, false)
3769	}
3770	haveWrapperTypes = nil
3771
3772	for _, typ := range needWrapperTypes {
3773		wrapType(typ, target, seen, true)
3774	}
3775	needWrapperTypes = nil
3776
3777	for _, wrapper := range haveMethodValueWrappers {
3778		wrapMethodValue(wrapper.rcvr, wrapper.method, target, false)
3779	}
3780	haveMethodValueWrappers = nil
3781
3782	for _, wrapper := range needMethodValueWrappers {
3783		wrapMethodValue(wrapper.rcvr, wrapper.method, target, true)
3784	}
3785	needMethodValueWrappers = nil
3786}
3787
3788func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
3789	key := typ.LinkString()
3790	if prev := seen[key]; prev != nil {
3791		if !types.Identical(typ, prev) {
3792			base.Fatalf("collision: types %v and %v have link string %q", typ, prev, key)
3793		}
3794		return
3795	}
3796	seen[key] = typ
3797
3798	if !needed {
3799		// Only called to add to 'seen'.
3800		return
3801	}
3802
3803	if !typ.IsInterface() {
3804		typecheck.CalcMethods(typ)
3805	}
3806	for _, meth := range typ.AllMethods() {
3807		if meth.Sym.IsBlank() || !meth.IsMethod() {
3808			base.FatalfAt(meth.Pos, "invalid method: %v", meth)
3809		}
3810
3811		methodWrapper(0, typ, meth, target)
3812
3813		// For non-interface types, we also want *T wrappers.
3814		if !typ.IsInterface() {
3815			methodWrapper(1, typ, meth, target)
3816
3817			// For not-in-heap types, *T is a scalar, not pointer shaped,
3818			// so the interface wrappers use **T.
3819			if typ.NotInHeap() {
3820				methodWrapper(2, typ, meth, target)
3821			}
3822		}
3823	}
3824}
3825
3826func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
3827	wrapper := tbase
3828	for i := 0; i < derefs; i++ {
3829		wrapper = types.NewPtr(wrapper)
3830	}
3831
3832	sym := ir.MethodSym(wrapper, method.Sym)
3833	base.Assertf(!sym.Siggen(), "already generated wrapper %v", sym)
3834	sym.SetSiggen(true)
3835
3836	wrappee := method.Type.Recv().Type
3837	if types.Identical(wrapper, wrappee) ||
3838		!types.IsMethodApplicable(wrapper, method) ||
3839		!reflectdata.NeedEmit(tbase) {
3840		return
3841	}
3842
3843	// TODO(mdempsky): Use method.Pos instead?
3844	pos := base.AutogeneratedPos
3845
3846	fn := newWrapperFunc(pos, sym, wrapper, method)
3847
3848	var recv ir.Node = fn.Nname.Type().Recv().Nname.(*ir.Name)
3849
3850	// For simple *T wrappers around T methods, panicwrap produces a
3851	// nicer panic message.
3852	if wrapper.IsPtr() && types.Identical(wrapper.Elem(), wrappee) {
3853		cond := ir.NewBinaryExpr(pos, ir.OEQ, recv, types.BuiltinPkg.Lookup("nil").Def.(ir.Node))
3854		then := []ir.Node{ir.NewCallExpr(pos, ir.OCALL, typecheck.LookupRuntime("panicwrap"), nil)}
3855		fn.Body.Append(ir.NewIfStmt(pos, cond, then, nil))
3856	}
3857
3858	// typecheck will add one implicit deref, if necessary,
3859	// but not-in-heap types require more for their **T wrappers.
3860	for i := 1; i < derefs; i++ {
3861		recv = Implicit(ir.NewStarExpr(pos, recv))
3862	}
3863
3864	addTailCall(pos, fn, recv, method)
3865
3866	finishWrapperFunc(fn, target)
3867}
3868
3869func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
3870	sym := ir.MethodSymSuffix(recvType, method.Sym, "-fm")
3871	if sym.Uniq() {
3872		return
3873	}
3874	sym.SetUniq(true)
3875
3876	// TODO(mdempsky): Use method.Pos instead?
3877	pos := base.AutogeneratedPos
3878
3879	fn := newWrapperFunc(pos, sym, nil, method)
3880	sym.Def = fn.Nname
3881
3882	// Declare and initialize variable holding receiver.
3883	recv := ir.NewHiddenParam(pos, fn, typecheck.Lookup(".this"), recvType)
3884
3885	if !needed {
3886		return
3887	}
3888
3889	addTailCall(pos, fn, recv, method)
3890
3891	finishWrapperFunc(fn, target)
3892}
3893
3894func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
3895	sig := newWrapperType(wrapper, method)
3896	fn := ir.NewFunc(pos, pos, sym, sig)
3897	fn.DeclareParams(true)
3898	fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers?
3899
3900	return fn
3901}
3902
3903func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
3904	ir.WithFunc(fn, func() {
3905		typecheck.Stmts(fn.Body)
3906	})
3907
3908	// We generate wrappers after the global inlining pass,
3909	// so we're responsible for applying inlining ourselves here.
3910	// TODO(prattmic): plumb PGO.
3911	interleaved.DevirtualizeAndInlineFunc(fn, nil)
3912
3913	// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
3914	// we don't know whether wrapper function has been generated for it or not, so
3915	// generate one immediately here.
3916	//
3917	// Further, after CL 492017, function that construct closures is allowed to be inlined,
3918	// even though the closure itself can't be inline. So we also need to visit body of any
3919	// closure that we see when visiting body of the wrapper function.
3920	ir.VisitFuncAndClosures(fn, func(n ir.Node) {
3921		if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
3922			wrapMethodValue(n.X.Type(), n.Selection, target, true)
3923		}
3924	})
3925
3926	fn.Nname.Defn = fn
3927	target.Funcs = append(target.Funcs, fn)
3928}
3929
3930// newWrapperType returns a copy of the given signature type, but with
3931// the receiver parameter type substituted with recvType.
3932// If recvType is nil, newWrapperType returns a signature
3933// without a receiver parameter.
3934func newWrapperType(recvType *types.Type, method *types.Field) *types.Type {
3935	clone := func(params []*types.Field) []*types.Field {
3936		res := make([]*types.Field, len(params))
3937		for i, param := range params {
3938			res[i] = types.NewField(param.Pos, param.Sym, param.Type)
3939			res[i].SetIsDDD(param.IsDDD())
3940		}
3941		return res
3942	}
3943
3944	sig := method.Type
3945
3946	var recv *types.Field
3947	if recvType != nil {
3948		recv = types.NewField(sig.Recv().Pos, sig.Recv().Sym, recvType)
3949	}
3950	params := clone(sig.Params())
3951	results := clone(sig.Results())
3952
3953	return types.NewSignature(recv, params, results)
3954}
3955
3956func addTailCall(pos src.XPos, fn *ir.Func, recv ir.Node, method *types.Field) {
3957	sig := fn.Nname.Type()
3958	args := make([]ir.Node, sig.NumParams())
3959	for i, param := range sig.Params() {
3960		args[i] = param.Nname.(*ir.Name)
3961	}
3962
3963	// TODO(mdempsky): Support creating OTAILCALL, when possible. See reflectdata.methodWrapper.
3964	// Not urgent though, because tail calls are currently incompatible with regabi anyway.
3965
3966	fn.SetWrapper(true) // TODO(mdempsky): Leave unset for tail calls?
3967
3968	dot := typecheck.XDotMethod(pos, recv, method.Sym, true)
3969	call := typecheck.Call(pos, dot, args, method.Type.IsVariadic()).(*ir.CallExpr)
3970
3971	if method.Type.NumResults() == 0 {
3972		fn.Body.Append(call)
3973		return
3974	}
3975
3976	ret := ir.NewReturnStmt(pos, nil)
3977	ret.Results = []ir.Node{call}
3978	fn.Body.Append(ret)
3979}
3980
3981func setBasePos(pos src.XPos) {
3982	// Set the position for any error messages we might print (e.g. too large types).
3983	base.Pos = pos
3984}
3985
3986// dictParamName is the name of the synthetic dictionary parameter
3987// added to shaped functions.
3988//
3989// N.B., this variable name is known to Delve:
3990// https://github.com/go-delve/delve/blob/cb91509630529e6055be845688fd21eb89ae8714/pkg/proc/eval.go#L28
3991const dictParamName = typecheck.LocalDictName
3992
3993// shapeSig returns a copy of fn's signature, except adding a
3994// dictionary parameter and promoting the receiver parameter (if any)
3995// to a normal parameter.
3996//
3997// The parameter types.Fields are all copied too, so their Nname
3998// fields can be initialized for use by the shape function.
3999func shapeSig(fn *ir.Func, dict *readerDict) *types.Type {
4000	sig := fn.Nname.Type()
4001	oldRecv := sig.Recv()
4002
4003	var recv *types.Field
4004	if oldRecv != nil {
4005		recv = types.NewField(oldRecv.Pos, oldRecv.Sym, oldRecv.Type)
4006	}
4007
4008	params := make([]*types.Field, 1+sig.NumParams())
4009	params[0] = types.NewField(fn.Pos(), fn.Sym().Pkg.Lookup(dictParamName), types.NewPtr(dict.varType()))
4010	for i, param := range sig.Params() {
4011		d := types.NewField(param.Pos, param.Sym, param.Type)
4012		d.SetIsDDD(param.IsDDD())
4013		params[1+i] = d
4014	}
4015
4016	results := make([]*types.Field, sig.NumResults())
4017	for i, result := range sig.Results() {
4018		results[i] = types.NewField(result.Pos, result.Sym, result.Type)
4019	}
4020
4021	return types.NewSignature(recv, params, results)
4022}
4023