1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file will evolve, since we plan to do a mix of stenciling and passing
6// around dictionaries.
7
8package noder
9
10import (
11	"cmd/compile/internal/base"
12	"cmd/compile/internal/inline"
13	"cmd/compile/internal/ir"
14	"cmd/compile/internal/objw"
15	"cmd/compile/internal/reflectdata"
16	"cmd/compile/internal/typecheck"
17	"cmd/compile/internal/types"
18	"cmd/internal/obj"
19	"cmd/internal/src"
20	"fmt"
21	"go/constant"
22)
23
24// Enable extra consistency checks.
25const doubleCheck = false
26
27func assert(p bool) {
28	base.Assert(p)
29}
30
31// For outputting debug information on dictionary format and instantiated dictionaries
32// (type arg, derived types, sub-dictionary, and itab entries).
33var infoPrintMode = false
34
35func infoPrint(format string, a ...interface{}) {
36	if infoPrintMode {
37		fmt.Printf(format, a...)
38	}
39}
40
41var geninst genInst
42
43func BuildInstantiations(preinliningMainScan bool) {
44	if geninst.instInfoMap == nil {
45		geninst.instInfoMap = make(map[*types.Sym]*instInfo)
46	}
47	geninst.buildInstantiations(preinliningMainScan)
48}
49
50// buildInstantiations scans functions for generic function calls and methods, and
51// creates the required instantiations. It also creates instantiated methods for all
52// fully-instantiated generic types that have been encountered already or new ones
53// that are encountered during the instantiation process. If preinliningMainScan is
54// true, it scans all declarations in typecheck.Target.Decls first, before scanning
55// any new instantiations created. If preinliningMainScan is false, we do not scan
56// any existing decls - we only scan method instantiations for any new
57// fully-instantiated types that we saw during inlining.
58func (g *genInst) buildInstantiations(preinliningMainScan bool) {
59	// Instantiate the methods of instantiated generic types that we have seen so far.
60	g.instantiateMethods()
61
62	if preinliningMainScan {
63		n := len(typecheck.Target.Decls)
64		for i := 0; i < n; i++ {
65			g.scanForGenCalls(typecheck.Target.Decls[i])
66		}
67	}
68
69	// Scan all new instantiations created due to g.instantiateMethods() and the
70	// scan of current decls (if done). This loop purposely runs until no new
71	// instantiations are created.
72	for i := 0; i < len(g.newInsts); i++ {
73		g.scanForGenCalls(g.newInsts[i])
74	}
75
76	g.finalizeSyms()
77
78	// All the instantiations and dictionaries have been created. Now go through
79	// each new instantiation and transform the various operations that need to make
80	// use of their dictionary.
81	l := len(g.newInsts)
82	for _, fun := range g.newInsts {
83		info := g.instInfoMap[fun.Sym()]
84		g.dictPass(info)
85		if !preinliningMainScan {
86			// Prepare for the round of inlining below.
87			inline.CanInline(fun.(*ir.Func))
88		}
89		if doubleCheck {
90			ir.Visit(info.fun, func(n ir.Node) {
91				if n.Op() != ir.OCONVIFACE {
92					return
93				}
94				c := n.(*ir.ConvExpr)
95				if c.X.Type().HasShape() && !c.X.Type().IsInterface() {
96					ir.Dump("BAD FUNCTION", info.fun)
97					ir.Dump("BAD CONVERSION", c)
98					base.Fatalf("converting shape type to interface")
99				}
100			})
101		}
102		if base.Flag.W > 1 {
103			ir.Dump(fmt.Sprintf("\ndictpass %v", info.fun), info.fun)
104		}
105	}
106	if !preinliningMainScan {
107		// Extra round of inlining for the new instantiations (only if
108		// preinliningMainScan is false, which means we have already done the
109		// main round of inlining)
110		for _, fun := range g.newInsts {
111			inline.InlineCalls(fun.(*ir.Func))
112			// New instantiations created during inlining should run
113			// ComputeAddrTaken directly, since we are past the main pass
114			// that did ComputeAddrTaken(). We could instead do this
115			// incrementally during stenciling (for all instantiations,
116			// including main ones before inlining), since we have the
117			// type information.
118			typecheck.ComputeAddrtaken(fun.(*ir.Func).Body)
119		}
120	}
121	assert(l == len(g.newInsts))
122	g.newInsts = nil
123}
124
125// scanForGenCalls scans a single function (or global assignment), looking for
126// references to generic functions/methods. At each such reference, it creates any
127// required instantiation and transforms the reference.
128func (g *genInst) scanForGenCalls(decl ir.Node) {
129	switch decl.Op() {
130	case ir.ODCLFUNC:
131		if decl.Type().HasTParam() {
132			// Skip any generic functions
133			return
134		}
135		// transformCall() below depends on CurFunc being set.
136		ir.CurFunc = decl.(*ir.Func)
137
138	case ir.OAS, ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV, ir.OASOP:
139		// These are all the various kinds of global assignments,
140		// whose right-hand-sides might contain a function
141		// instantiation.
142
143	default:
144		// The other possible ops at the top level are ODCLCONST
145		// and ODCLTYPE, which don't have any function
146		// instantiations.
147		return
148	}
149
150	// Search for any function references using generic function/methods. Then
151	// create the needed instantiated function if it hasn't been created yet, and
152	// change to calling that function directly.
153	modified := false
154	closureRequired := false
155	// declInfo will be non-nil exactly if we are scanning an instantiated function
156	declInfo := g.instInfoMap[decl.Sym()]
157
158	ir.Visit(decl, func(n ir.Node) {
159		if n.Op() == ir.OFUNCINST {
160			// generic F, not immediately called
161			closureRequired = true
162		}
163		if (n.Op() == ir.OMETHEXPR || n.Op() == ir.OMETHVALUE) && len(deref(n.(*ir.SelectorExpr).X.Type()).RParams()) > 0 && !types.IsInterfaceMethod(n.(*ir.SelectorExpr).Selection.Type) {
164			// T.M or x.M, where T or x is generic, but not immediately
165			// called. Not necessary if the method selected is
166			// actually for an embedded interface field.
167			closureRequired = true
168		}
169		if n.Op() == ir.OCALL && n.(*ir.CallExpr).X.Op() == ir.OFUNCINST {
170			// We have found a function call using a generic function
171			// instantiation.
172			call := n.(*ir.CallExpr)
173			inst := call.X.(*ir.InstExpr)
174			nameNode, isMeth := g.getInstNameNode(inst)
175			targs := typecheck.TypesOf(inst.Targs)
176			st := g.getInstantiation(nameNode, targs, isMeth).fun
177			dictValue, usingSubdict := g.getDictOrSubdict(declInfo, n, nameNode, targs, isMeth)
178			if infoPrintMode {
179				dictkind := "Main dictionary"
180				if usingSubdict {
181					dictkind = "Sub-dictionary"
182				}
183				if inst.X.Op() == ir.OMETHVALUE {
184					fmt.Printf("%s in %v at generic method call: %v - %v\n", dictkind, decl, inst.X, call)
185				} else {
186					fmt.Printf("%s in %v at generic function call: %v - %v\n", dictkind, decl, inst.X, call)
187				}
188			}
189
190			// Transform the Call now, which changes OCALL to
191			// OCALLFUNC and does typecheckaste/assignconvfn. Do
192			// it before installing the instantiation, so we are
193			// checking against non-shape param types in
194			// typecheckaste.
195			transformCall(call)
196
197			// Replace the OFUNCINST with a direct reference to the
198			// new stenciled function
199			call.X = st.Nname
200			if inst.X.Op() == ir.OMETHVALUE {
201				// When we create an instantiation of a method
202				// call, we make it a function. So, move the
203				// receiver to be the first arg of the function
204				// call.
205				call.Args.Prepend(inst.X.(*ir.SelectorExpr).X)
206			}
207
208			// Add dictionary to argument list.
209			call.Args.Prepend(dictValue)
210			modified = true
211		}
212		if n.Op() == ir.OCALLMETH && n.(*ir.CallExpr).X.Op() == ir.ODOTMETH && len(deref(n.(*ir.CallExpr).X.Type().Recv().Type).RParams()) > 0 {
213			// Method call on a generic type, which was instantiated by stenciling.
214			// Method calls on explicitly instantiated types will have an OFUNCINST
215			// and are handled above.
216			call := n.(*ir.CallExpr)
217			meth := call.X.(*ir.SelectorExpr)
218			targs := deref(meth.Type().Recv().Type).RParams()
219
220			t := meth.X.Type()
221			baseSym := deref(t).OrigSym()
222			baseType := baseSym.Def.(*ir.Name).Type()
223			var gf *ir.Name
224			for _, m := range baseType.Methods().Slice() {
225				if meth.Sel == m.Sym {
226					gf = m.Nname.(*ir.Name)
227					break
228				}
229			}
230
231			// Transform the Call now, which changes OCALL
232			// to OCALLFUNC and does typecheckaste/assignconvfn.
233			transformCall(call)
234
235			st := g.getInstantiation(gf, targs, true).fun
236			dictValue, usingSubdict := g.getDictOrSubdict(declInfo, n, gf, targs, true)
237			// We have to be using a subdictionary, since this is
238			// a generic method call.
239			assert(usingSubdict)
240
241			// Transform to a function call, by appending the
242			// dictionary and the receiver to the args.
243			call.SetOp(ir.OCALLFUNC)
244			call.X = st.Nname
245			call.Args.Prepend(dictValue, meth.X)
246			modified = true
247		}
248	})
249
250	// If we found a reference to a generic instantiation that wasn't an
251	// immediate call, then traverse the nodes of decl again (with
252	// EditChildren rather than Visit), where we actually change the
253	// reference to the instantiation to a closure that captures the
254	// dictionary, then does a direct call.
255	// EditChildren is more expensive than Visit, so we only do this
256	// in the infrequent case of an OFUNCINST without a corresponding
257	// call.
258	if closureRequired {
259		modified = true
260		var edit func(ir.Node) ir.Node
261		var outer *ir.Func
262		if f, ok := decl.(*ir.Func); ok {
263			outer = f
264		}
265		edit = func(x ir.Node) ir.Node {
266			if x.Op() == ir.OFUNCINST {
267				child := x.(*ir.InstExpr).X
268				if child.Op() == ir.OMETHEXPR || child.Op() == ir.OMETHVALUE {
269					// Call EditChildren on child (x.X),
270					// not x, so that we don't do
271					// buildClosure() on the
272					// METHEXPR/METHVALUE nodes as well.
273					ir.EditChildren(child, edit)
274					return g.buildClosure(outer, x)
275				}
276			}
277			ir.EditChildren(x, edit)
278			switch {
279			case x.Op() == ir.OFUNCINST:
280				return g.buildClosure(outer, x)
281			case (x.Op() == ir.OMETHEXPR || x.Op() == ir.OMETHVALUE) &&
282				len(deref(x.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
283				!types.IsInterfaceMethod(x.(*ir.SelectorExpr).Selection.Type):
284				return g.buildClosure(outer, x)
285			}
286			return x
287		}
288		edit(decl)
289	}
290	if base.Flag.W > 1 && modified {
291		ir.Dump(fmt.Sprintf("\nmodified %v", decl), decl)
292	}
293	ir.CurFunc = nil
294	// We may have seen new fully-instantiated generic types while
295	// instantiating any needed functions/methods in the above
296	// function. If so, instantiate all the methods of those types
297	// (which will then lead to more function/methods to scan in the loop).
298	g.instantiateMethods()
299}
300
301// buildClosure makes a closure to implement x, a OFUNCINST or OMETHEXPR/OMETHVALUE
302// of generic type. outer is the containing function (or nil if closure is
303// in a global assignment instead of a function).
304func (g *genInst) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
305	pos := x.Pos()
306	var target *ir.Func   // target instantiated function/method
307	var dictValue ir.Node // dictionary to use
308	var rcvrValue ir.Node // receiver, if a method value
309	typ := x.Type()       // type of the closure
310	var outerInfo *instInfo
311	if outer != nil {
312		outerInfo = g.instInfoMap[outer.Sym()]
313	}
314	usingSubdict := false
315	valueMethod := false
316	if x.Op() == ir.OFUNCINST {
317		inst := x.(*ir.InstExpr)
318
319		// Type arguments we're instantiating with.
320		targs := typecheck.TypesOf(inst.Targs)
321
322		// Find the generic function/method.
323		var gf *ir.Name
324		if inst.X.Op() == ir.ONAME {
325			// Instantiating a generic function call.
326			gf = inst.X.(*ir.Name)
327		} else if inst.X.Op() == ir.OMETHVALUE {
328			// Instantiating a method value x.M.
329			se := inst.X.(*ir.SelectorExpr)
330			rcvrValue = se.X
331			gf = se.Selection.Nname.(*ir.Name)
332		} else {
333			panic("unhandled")
334		}
335
336		// target is the instantiated function we're trying to call.
337		// For functions, the target expects a dictionary as its first argument.
338		// For method values, the target expects a dictionary and the receiver
339		// as its first two arguments.
340		// dictValue is the value to use for the dictionary argument.
341		target = g.getInstantiation(gf, targs, rcvrValue != nil).fun
342		dictValue, usingSubdict = g.getDictOrSubdict(outerInfo, x, gf, targs, rcvrValue != nil)
343		if infoPrintMode {
344			dictkind := "Main dictionary"
345			if usingSubdict {
346				dictkind = "Sub-dictionary"
347			}
348			if rcvrValue == nil {
349				fmt.Printf("%s in %v for generic function value %v\n", dictkind, outer, inst.X)
350			} else {
351				fmt.Printf("%s in %v for generic method value %v\n", dictkind, outer, inst.X)
352			}
353		}
354	} else { // ir.OMETHEXPR or ir.METHVALUE
355		// Method expression T.M where T is a generic type.
356		se := x.(*ir.SelectorExpr)
357		targs := deref(se.X.Type()).RParams()
358		if len(targs) == 0 {
359			panic("bad")
360		}
361		if x.Op() == ir.OMETHVALUE {
362			rcvrValue = se.X
363		}
364
365		// se.X.Type() is the top-level type of the method expression. To
366		// correctly handle method expressions involving embedded fields,
367		// look up the generic method below using the type of the receiver
368		// of se.Selection, since that will be the type that actually has
369		// the method.
370		recv := deref(se.Selection.Type.Recv().Type)
371		if len(recv.RParams()) == 0 {
372			// The embedded type that actually has the method is not
373			// actually generic, so no need to build a closure.
374			return x
375		}
376		baseType := recv.OrigSym().Def.Type()
377		var gf *ir.Name
378		for _, m := range baseType.Methods().Slice() {
379			if se.Sel == m.Sym {
380				gf = m.Nname.(*ir.Name)
381				break
382			}
383		}
384		if !gf.Type().Recv().Type.IsPtr() {
385			// Remember if value method, so we can detect (*T).M case.
386			valueMethod = true
387		}
388		target = g.getInstantiation(gf, targs, true).fun
389		dictValue, usingSubdict = g.getDictOrSubdict(outerInfo, x, gf, targs, true)
390		if infoPrintMode {
391			dictkind := "Main dictionary"
392			if usingSubdict {
393				dictkind = "Sub-dictionary"
394			}
395			fmt.Printf("%s in %v for method expression %v\n", dictkind, outer, x)
396		}
397	}
398
399	// Build a closure to implement a function instantiation.
400	//
401	//   func f[T any] (int, int) (int, int) { ...whatever... }
402	//
403	// Then any reference to f[int] not directly called gets rewritten to
404	//
405	//   .dictN := ... dictionary to use ...
406	//   func(a0, a1 int) (r0, r1 int) {
407	//     return .inst.f[int](.dictN, a0, a1)
408	//   }
409	//
410	// Similarly for method expressions,
411	//
412	//   type g[T any] ....
413	//   func (rcvr g[T]) f(a0, a1 int) (r0, r1 int) { ... }
414	//
415	// Any reference to g[int].f not directly called gets rewritten to
416	//
417	//   .dictN := ... dictionary to use ...
418	//   func(rcvr g[int], a0, a1 int) (r0, r1 int) {
419	//     return .inst.g[int].f(.dictN, rcvr, a0, a1)
420	//   }
421	//
422	// Also method values
423	//
424	//   var x g[int]
425	//
426	// Any reference to x.f not directly called gets rewritten to
427	//
428	//   .dictN := ... dictionary to use ...
429	//   x2 := x
430	//   func(a0, a1 int) (r0, r1 int) {
431	//     return .inst.g[int].f(.dictN, x2, a0, a1)
432	//   }
433
434	// Make a new internal function.
435	fn, formalParams, formalResults := startClosure(pos, outer, typ)
436
437	// This is the dictionary we want to use.
438	// It may be a constant, or it may be a dictionary acquired from the outer function's dictionary.
439	// For the latter, dictVar is a variable in the outer function's scope, set to the subdictionary
440	// read from the outer function's dictionary.
441	var dictVar *ir.Name
442	var dictAssign *ir.AssignStmt
443	if outer != nil {
444		dictVar = ir.NewNameAt(pos, typecheck.LookupNum(typecheck.LocalDictName, g.dnum))
445		g.dnum++
446		dictVar.Class = ir.PAUTO
447		typed(types.Types[types.TUINTPTR], dictVar)
448		dictVar.Curfn = outer
449		dictAssign = ir.NewAssignStmt(pos, dictVar, dictValue)
450		dictAssign.SetTypecheck(1)
451		dictVar.Defn = dictAssign
452		outer.Dcl = append(outer.Dcl, dictVar)
453	}
454	// assign the receiver to a temporary.
455	var rcvrVar *ir.Name
456	var rcvrAssign ir.Node
457	if rcvrValue != nil {
458		rcvrVar = ir.NewNameAt(pos, typecheck.LookupNum(".rcvr", g.dnum))
459		g.dnum++
460		typed(rcvrValue.Type(), rcvrVar)
461		rcvrAssign = ir.NewAssignStmt(pos, rcvrVar, rcvrValue)
462		rcvrAssign.SetTypecheck(1)
463		rcvrVar.Defn = rcvrAssign
464		if outer == nil {
465			rcvrVar.Class = ir.PEXTERN
466			typecheck.Target.Decls = append(typecheck.Target.Decls, rcvrAssign)
467			typecheck.Target.Externs = append(typecheck.Target.Externs, rcvrVar)
468		} else {
469			rcvrVar.Class = ir.PAUTO
470			rcvrVar.Curfn = outer
471			outer.Dcl = append(outer.Dcl, rcvrVar)
472		}
473	}
474
475	// Build body of closure. This involves just calling the wrapped function directly
476	// with the additional dictionary argument.
477
478	// First, figure out the dictionary argument.
479	var dict2Var ir.Node
480	if usingSubdict {
481		// Capture sub-dictionary calculated in the outer function
482		dict2Var = ir.CaptureName(pos, fn, dictVar)
483		typed(types.Types[types.TUINTPTR], dict2Var)
484	} else {
485		// Static dictionary, so can be used directly in the closure
486		dict2Var = dictValue
487	}
488	// Also capture the receiver variable.
489	var rcvr2Var *ir.Name
490	if rcvrValue != nil {
491		rcvr2Var = ir.CaptureName(pos, fn, rcvrVar)
492	}
493
494	// Build arguments to call inside the closure.
495	var args []ir.Node
496
497	// First the dictionary argument.
498	args = append(args, dict2Var)
499	// Then the receiver.
500	if rcvrValue != nil {
501		args = append(args, rcvr2Var)
502	}
503	// Then all the other arguments (including receiver for method expressions).
504	for i := 0; i < typ.NumParams(); i++ {
505		if x.Op() == ir.OMETHEXPR && i == 0 {
506			// If we are doing a method expression, we need to
507			// explicitly traverse any embedded fields in the receiver
508			// argument in order to call the method instantiation.
509			arg0 := formalParams[0].Nname.(ir.Node)
510			arg0 = typecheck.AddImplicitDots(ir.NewSelectorExpr(x.Pos(), ir.OXDOT, arg0, x.(*ir.SelectorExpr).Sel)).X
511			if valueMethod && arg0.Type().IsPtr() {
512				// For handling the (*T).M case: if we have a pointer
513				// receiver after following all the embedded fields,
514				// but it's a value method, add a star operator.
515				arg0 = ir.NewStarExpr(arg0.Pos(), arg0)
516			}
517			args = append(args, arg0)
518		} else {
519			args = append(args, formalParams[i].Nname.(*ir.Name))
520		}
521	}
522
523	// Build call itself.
524	var innerCall ir.Node = ir.NewCallExpr(pos, ir.OCALL, target.Nname, args)
525	innerCall.(*ir.CallExpr).IsDDD = typ.IsVariadic()
526	if len(formalResults) > 0 {
527		innerCall = ir.NewReturnStmt(pos, []ir.Node{innerCall})
528	}
529	// Finish building body of closure.
530	ir.CurFunc = fn
531	// TODO: set types directly here instead of using typecheck.Stmt
532	typecheck.Stmt(innerCall)
533	ir.CurFunc = nil
534	fn.Body = []ir.Node{innerCall}
535
536	// We're all done with the captured dictionary (and receiver, for method values).
537	ir.FinishCaptureNames(pos, outer, fn)
538
539	// Make a closure referencing our new internal function.
540	c := ir.UseClosure(fn.OClosure, typecheck.Target)
541	var init []ir.Node
542	if outer != nil {
543		init = append(init, dictAssign)
544	}
545	if rcvrValue != nil {
546		init = append(init, rcvrAssign)
547	}
548	return ir.InitExpr(init, c)
549}
550
551// instantiateMethods instantiates all the methods (and associated dictionaries) of
552// all fully-instantiated generic types that have been added to typecheck.instTypeList.
553// It continues until no more types are added to typecheck.instTypeList.
554func (g *genInst) instantiateMethods() {
555	for {
556		instTypeList := typecheck.GetInstTypeList()
557		if len(instTypeList) == 0 {
558			break
559		}
560		typecheck.ClearInstTypeList()
561		for _, typ := range instTypeList {
562			assert(!typ.HasShape())
563			// Mark runtime type as needed, since this ensures that the
564			// compiler puts out the needed DWARF symbols, when this
565			// instantiated type has a different package from the local
566			// package.
567			typecheck.NeedRuntimeType(typ)
568			// Lookup the method on the base generic type, since methods may
569			// not be set on imported instantiated types.
570			baseSym := typ.OrigSym()
571			baseType := baseSym.Def.(*ir.Name).Type()
572			for j, _ := range typ.Methods().Slice() {
573				if baseType.Methods().Slice()[j].Nointerface() {
574					typ.Methods().Slice()[j].SetNointerface(true)
575				}
576				baseNname := baseType.Methods().Slice()[j].Nname.(*ir.Name)
577				// Eagerly generate the instantiations and dictionaries that implement these methods.
578				// We don't use the instantiations here, just generate them (and any
579				// further instantiations those generate, etc.).
580				// Note that we don't set the Func for any methods on instantiated
581				// types. Their signatures don't match so that would be confusing.
582				// Direct method calls go directly to the instantiations, implemented above.
583				// Indirect method calls use wrappers generated in reflectcall. Those wrappers
584				// will use these instantiations if they are needed (for interface tables or reflection).
585				_ = g.getInstantiation(baseNname, typ.RParams(), true)
586				_ = g.getDictionarySym(baseNname, typ.RParams(), true)
587			}
588		}
589	}
590}
591
592// getInstNameNode returns the name node for the method or function being instantiated, and a bool which is true if a method is being instantiated.
593func (g *genInst) getInstNameNode(inst *ir.InstExpr) (*ir.Name, bool) {
594	if meth, ok := inst.X.(*ir.SelectorExpr); ok {
595		return meth.Selection.Nname.(*ir.Name), true
596	} else {
597		return inst.X.(*ir.Name), false
598	}
599}
600
601// getDictOrSubdict returns, for a method/function call or reference (node n) in an
602// instantiation (described by instInfo), a node which is accessing a sub-dictionary
603// or main/static dictionary, as needed, and also returns a boolean indicating if a
604// sub-dictionary was accessed. nameNode is the particular function or method being
605// called/referenced, and targs are the type arguments.
606func (g *genInst) getDictOrSubdict(declInfo *instInfo, n ir.Node, nameNode *ir.Name, targs []*types.Type, isMeth bool) (ir.Node, bool) {
607	var dict ir.Node
608	usingSubdict := false
609	if declInfo != nil {
610		entry := -1
611		for i, de := range declInfo.dictInfo.subDictCalls {
612			if n == de {
613				entry = declInfo.dictInfo.startSubDict + i
614				break
615			}
616		}
617		// If the entry is not found, it may be that this node did not have
618		// any type args that depend on type params, so we need a main
619		// dictionary, not a sub-dictionary.
620		if entry >= 0 {
621			dict = getDictionaryEntry(n.Pos(), declInfo.dictParam, entry, declInfo.dictInfo.dictLen)
622			usingSubdict = true
623		}
624	}
625	if !usingSubdict {
626		dict = g.getDictionaryValue(n.Pos(), nameNode, targs, isMeth)
627	}
628	return dict, usingSubdict
629}
630
631// checkFetchBody checks if a generic body can be fetched, but hasn't been loaded
632// yet. If so, it imports the body.
633func checkFetchBody(nameNode *ir.Name) {
634	if nameNode.Func.Body == nil && nameNode.Func.Inl != nil {
635		// If there is no body yet but Func.Inl exists, then we can
636		// import the whole generic body.
637		assert(nameNode.Func.Inl.Cost == 1 && nameNode.Sym().Pkg != types.LocalPkg)
638		typecheck.ImportBody(nameNode.Func)
639		assert(nameNode.Func.Inl.Body != nil)
640		nameNode.Func.Body = nameNode.Func.Inl.Body
641		nameNode.Func.Dcl = nameNode.Func.Inl.Dcl
642	}
643}
644
645// getInstantiation gets the instantiantion and dictionary of the function or method nameNode
646// with the type arguments shapes. If the instantiated function is not already
647// cached, then it calls genericSubst to create the new instantiation.
648func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMeth bool) *instInfo {
649	if nameNode.Func == nil {
650		// If nameNode.Func is nil, this must be a reference to a method of
651		// an imported instantiated type. We will have already called
652		// g.instantiateMethods() on the fully-instantiated type, so
653		// g.instInfoMap[sym] will be non-nil below.
654		rcvr := nameNode.Type().Recv()
655		if rcvr == nil || !deref(rcvr.Type).IsFullyInstantiated() {
656			base.FatalfAt(nameNode.Pos(), "Unexpected function instantiation %v with no body", nameNode)
657		}
658	} else {
659		checkFetchBody(nameNode)
660	}
661
662	// Convert any non-shape type arguments to their shape, so we can reduce the
663	// number of instantiations we have to generate. You can actually have a mix
664	// of shape and non-shape arguments, because of inferred or explicitly
665	// specified concrete type args.
666	s1 := make([]*types.Type, len(shapes))
667	for i, t := range shapes {
668		if !t.IsShape() {
669			s1[i] = typecheck.Shapify(t, i)
670		} else {
671			// Already a shape, but make sure it has the correct index.
672			s1[i] = typecheck.Shapify(shapes[i].Underlying(), i)
673		}
674	}
675	shapes = s1
676
677	sym := typecheck.MakeFuncInstSym(nameNode.Sym(), shapes, false, isMeth)
678	info := g.instInfoMap[sym]
679	if info == nil {
680		// If instantiation doesn't exist yet, create it and add
681		// to the list of decls.
682		info = &instInfo{
683			dictInfo: &dictInfo{},
684		}
685		info.dictInfo.shapeToBound = make(map[*types.Type]*types.Type)
686
687		if sym.Def != nil {
688			// This instantiation must have been imported from another
689			// package (because it was needed for inlining), so we should
690			// not re-generate it and have conflicting definitions for the
691			// symbol (issue #50121). It will have already gone through the
692			// dictionary transformations of dictPass, so we don't actually
693			// need the info.dictParam and info.shapeToBound info filled in
694			// below. We just set the imported instantiation as info.fun.
695			assert(sym.Pkg != types.LocalPkg)
696			info.fun = sym.Def.(*ir.Name).Func
697			assert(info.fun != nil)
698			g.instInfoMap[sym] = info
699			return info
700		}
701
702		// genericSubst fills in info.dictParam and info.shapeToBound.
703		st := g.genericSubst(sym, nameNode, shapes, isMeth, info)
704		info.fun = st
705		g.instInfoMap[sym] = info
706
707		// getInstInfo fills in info.dictInfo.
708		g.getInstInfo(st, shapes, info)
709		if base.Flag.W > 1 {
710			ir.Dump(fmt.Sprintf("\nstenciled %v", st), st)
711		}
712
713		// This ensures that the linker drops duplicates of this instantiation.
714		// All just works!
715		st.SetDupok(true)
716		typecheck.Target.Decls = append(typecheck.Target.Decls, st)
717		g.newInsts = append(g.newInsts, st)
718	}
719	return info
720}
721
722// Struct containing info needed for doing the substitution as we create the
723// instantiation of a generic function with specified type arguments.
724type subster struct {
725	g        *genInst
726	isMethod bool     // If a method is being instantiated
727	newf     *ir.Func // Func node for the new stenciled function
728	ts       typecheck.Tsubster
729	info     *instInfo // Place to put extra info in the instantiation
730
731	// Map from non-nil, non-ONAME node n to slice of all m, where m.Defn = n
732	defnMap map[ir.Node][]**ir.Name
733}
734
735// genericSubst returns a new function with name newsym. The function is an
736// instantiation of a generic function or method specified by namedNode with type
737// args shapes. For a method with a generic receiver, it returns an instantiated
738// function type where the receiver becomes the first parameter. For either a generic
739// method or function, a dictionary parameter is the added as the very first
740// parameter. genericSubst fills in info.dictParam and info.shapeToBound.
741func (g *genInst) genericSubst(newsym *types.Sym, nameNode *ir.Name, shapes []*types.Type, isMethod bool, info *instInfo) *ir.Func {
742	var tparams []*types.Type
743	if isMethod {
744		// Get the type params from the method receiver (after skipping
745		// over any pointer)
746		recvType := nameNode.Type().Recv().Type
747		recvType = deref(recvType)
748		tparams = recvType.RParams()
749	} else {
750		fields := nameNode.Type().TParams().Fields().Slice()
751		tparams = make([]*types.Type, len(fields))
752		for i, f := range fields {
753			tparams[i] = f.Type
754		}
755	}
756	gf := nameNode.Func
757	// Pos of the instantiated function is same as the generic function
758	newf := ir.NewFunc(gf.Pos())
759	newf.Pragma = gf.Pragma // copy over pragmas from generic function to stenciled implementation.
760	newf.Nname = ir.NewNameAt(gf.Pos(), newsym)
761	newf.Nname.Func = newf
762	newf.Nname.Defn = newf
763	newsym.Def = newf.Nname
764	savef := ir.CurFunc
765	// transformCall/transformReturn (called during stenciling of the body)
766	// depend on ir.CurFunc being set.
767	ir.CurFunc = newf
768
769	assert(len(tparams) == len(shapes))
770
771	subst := &subster{
772		g:        g,
773		isMethod: isMethod,
774		newf:     newf,
775		info:     info,
776		ts: typecheck.Tsubster{
777			Tparams: tparams,
778			Targs:   shapes,
779			Vars:    make(map[*ir.Name]*ir.Name),
780		},
781		defnMap: make(map[ir.Node][]**ir.Name),
782	}
783
784	newf.Dcl = make([]*ir.Name, 0, len(gf.Dcl)+1)
785
786	// Create the needed dictionary param
787	dictionarySym := newsym.Pkg.Lookup(typecheck.LocalDictName)
788	dictionaryType := types.Types[types.TUINTPTR]
789	dictionaryName := ir.NewNameAt(gf.Pos(), dictionarySym)
790	typed(dictionaryType, dictionaryName)
791	dictionaryName.Class = ir.PPARAM
792	dictionaryName.Curfn = newf
793	newf.Dcl = append(newf.Dcl, dictionaryName)
794	for _, n := range gf.Dcl {
795		if n.Sym().Name == typecheck.LocalDictName {
796			panic("already has dictionary")
797		}
798		newf.Dcl = append(newf.Dcl, subst.localvar(n))
799	}
800	dictionaryArg := types.NewField(gf.Pos(), dictionarySym, dictionaryType)
801	dictionaryArg.Nname = dictionaryName
802	info.dictParam = dictionaryName
803
804	// We add the dictionary as the first parameter in the function signature.
805	// We also transform a method type to the corresponding function type
806	// (make the receiver be the next parameter after the dictionary).
807	oldt := nameNode.Type()
808	var args []*types.Field
809	args = append(args, dictionaryArg)
810	args = append(args, oldt.Recvs().FieldSlice()...)
811	args = append(args, oldt.Params().FieldSlice()...)
812
813	// Replace the types in the function signature via subst.fields.
814	// Ugly: also, we have to insert the Name nodes of the parameters/results into
815	// the function type. The current function type has no Nname fields set,
816	// because it came via conversion from the types2 type.
817	newt := types.NewSignature(oldt.Pkg(), nil, nil,
818		subst.fields(ir.PPARAM, args, newf.Dcl),
819		subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), newf.Dcl))
820
821	typed(newt, newf.Nname)
822	ir.MarkFunc(newf.Nname)
823	newf.SetTypecheck(1)
824
825	// Make sure name/type of newf is set before substituting the body.
826	newf.Body = subst.list(gf.Body)
827	if len(newf.Body) == 0 {
828		// Ensure the body is nonempty, for issue 49524.
829		// TODO: have some other way to detect the difference between
830		// a function declared with no body, vs. one with an empty body?
831		newf.Body = append(newf.Body, ir.NewBlockStmt(gf.Pos(), nil))
832	}
833
834	if len(subst.defnMap) > 0 {
835		base.Fatalf("defnMap is not empty")
836	}
837
838	for i, tp := range tparams {
839		info.dictInfo.shapeToBound[shapes[i]] = subst.ts.Typ(tp.Bound())
840	}
841
842	ir.CurFunc = savef
843
844	return subst.newf
845}
846
847// localvar creates a new name node for the specified local variable and enters it
848// in subst.vars. It substitutes type arguments for type parameters in the type of
849// name as needed.
850func (subst *subster) localvar(name *ir.Name) *ir.Name {
851	m := ir.NewNameAt(name.Pos(), name.Sym())
852	if name.IsClosureVar() {
853		m.SetIsClosureVar(true)
854	}
855	m.SetType(subst.ts.Typ(name.Type()))
856	m.BuiltinOp = name.BuiltinOp
857	m.Curfn = subst.newf
858	m.Class = name.Class
859	assert(name.Class != ir.PEXTERN && name.Class != ir.PFUNC)
860	m.Func = name.Func
861	subst.ts.Vars[name] = m
862	m.SetTypecheck(1)
863	m.DictIndex = name.DictIndex
864	if name.Defn != nil {
865		if name.Defn.Op() == ir.ONAME {
866			// This is a closure variable, so its Defn is the outer
867			// captured variable, which has already been substituted.
868			m.Defn = subst.node(name.Defn)
869		} else {
870			// The other values of Defn are nodes in the body of the
871			// function, so just remember the mapping so we can set Defn
872			// properly in node() when we create the new body node. We
873			// always call localvar() on all the local variables before
874			// we substitute the body.
875			slice := subst.defnMap[name.Defn]
876			subst.defnMap[name.Defn] = append(slice, &m)
877		}
878	}
879	if name.Outer != nil {
880		m.Outer = subst.node(name.Outer).(*ir.Name)
881	}
882
883	return m
884}
885
886// getDictionaryEntry gets the i'th entry in the dictionary dict.
887func getDictionaryEntry(pos src.XPos, dict *ir.Name, i int, size int) ir.Node {
888	// Convert dictionary to *[N]uintptr
889	// All entries in the dictionary are pointers. They all point to static data, though, so we
890	// treat them as uintptrs so the GC doesn't need to keep track of them.
891	d := ir.NewConvExpr(pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], dict)
892	d.SetTypecheck(1)
893	d = ir.NewConvExpr(pos, ir.OCONVNOP, types.NewArray(types.Types[types.TUINTPTR], int64(size)).PtrTo(), d)
894	d.SetTypecheck(1)
895	types.CheckSize(d.Type().Elem())
896
897	// Load entry i out of the dictionary.
898	deref := ir.NewStarExpr(pos, d)
899	typed(d.Type().Elem(), deref)
900	idx := ir.NewConstExpr(constant.MakeUint64(uint64(i)), dict) // TODO: what to set orig to?
901	typed(types.Types[types.TUINTPTR], idx)
902	r := ir.NewIndexExpr(pos, deref, idx)
903	typed(types.Types[types.TUINTPTR], r)
904	return r
905}
906
907// getDictionaryType returns a *runtime._type from the dictionary entry i (which
908// refers to a type param or a derived type that uses type params). It uses the
909// specified dictionary dictParam, rather than the one in info.dictParam.
910func getDictionaryType(info *instInfo, dictParam *ir.Name, pos src.XPos, i int) ir.Node {
911	if i < 0 || i >= info.dictInfo.startSubDict {
912		base.Fatalf(fmt.Sprintf("bad dict index %d", i))
913	}
914
915	r := getDictionaryEntry(pos, info.dictParam, i, info.dictInfo.startSubDict)
916	// change type of retrieved dictionary entry to *byte, which is the
917	// standard typing of a *runtime._type in the compiler
918	typed(types.Types[types.TUINT8].PtrTo(), r)
919	return r
920}
921
922// node is like DeepCopy(), but substitutes ONAME nodes based on subst.ts.vars, and
923// also descends into closures. It substitutes type arguments for type parameters in
924// all the new nodes and does the transformations that were delayed on the generic
925// function.
926func (subst *subster) node(n ir.Node) ir.Node {
927	// Use closure to capture all state needed by the ir.EditChildren argument.
928	var edit func(ir.Node) ir.Node
929	edit = func(x ir.Node) ir.Node {
930		// Analogous to ir.SetPos() at beginning of typecheck.typecheck() -
931		// allows using base.Pos during the transform functions, just like
932		// the tc*() functions.
933		ir.SetPos(x)
934		switch x.Op() {
935		case ir.OTYPE:
936			return ir.TypeNode(subst.ts.Typ(x.Type()))
937
938		case ir.ONAME:
939			if v := subst.ts.Vars[x.(*ir.Name)]; v != nil {
940				return v
941			}
942			if ir.IsBlank(x) {
943				// Special case, because a blank local variable is
944				// not in the fn.Dcl list.
945				m := ir.NewNameAt(x.Pos(), ir.BlankNode.Sym())
946				return typed(subst.ts.Typ(x.Type()), m)
947			}
948			return x
949		case ir.ONONAME:
950			// This handles the identifier in a type switch guard
951			fallthrough
952		case ir.OLITERAL, ir.ONIL:
953			if x.Sym() != nil {
954				return x
955			}
956		}
957		m := ir.Copy(x)
958
959		slice, ok := subst.defnMap[x]
960		if ok {
961			// We just copied a non-ONAME node which was the Defn value
962			// of a local variable. Set the Defn value of the copied
963			// local variable to this new Defn node.
964			for _, ptr := range slice {
965				(*ptr).Defn = m
966			}
967			delete(subst.defnMap, x)
968		}
969
970		if _, isExpr := m.(ir.Expr); isExpr {
971			t := x.Type()
972			if t == nil {
973				// Check for known cases where t can be nil (call
974				// that has no return values, and key expressions)
975				// and otherwise cause a fatal error.
976				_, isCallExpr := m.(*ir.CallExpr)
977				_, isStructKeyExpr := m.(*ir.StructKeyExpr)
978				_, isKeyExpr := m.(*ir.KeyExpr)
979				if !isCallExpr && !isStructKeyExpr && !isKeyExpr && x.Op() != ir.OPANIC &&
980					x.Op() != ir.OCLOSE {
981					base.FatalfAt(m.Pos(), "Nil type for %v", x)
982				}
983			} else if x.Op() != ir.OCLOSURE {
984				m.SetType(subst.ts.Typ(x.Type()))
985			}
986		}
987
988		ir.EditChildren(m, edit)
989
990		m.SetTypecheck(1)
991
992		// Do the transformations that we delayed on the generic function
993		// node, now that we have substituted in the type args.
994		switch x.Op() {
995		case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
996			transformCompare(m.(*ir.BinaryExpr))
997
998		case ir.OSLICE, ir.OSLICE3:
999			transformSlice(m.(*ir.SliceExpr))
1000
1001		case ir.OADD:
1002			m = transformAdd(m.(*ir.BinaryExpr))
1003
1004		case ir.OINDEX:
1005			transformIndex(m.(*ir.IndexExpr))
1006
1007		case ir.OAS2:
1008			as2 := m.(*ir.AssignListStmt)
1009			transformAssign(as2, as2.Lhs, as2.Rhs)
1010
1011		case ir.OAS:
1012			as := m.(*ir.AssignStmt)
1013			if as.Y != nil {
1014				// transformAssign doesn't handle the case
1015				// of zeroing assignment of a dcl (rhs[0] is nil).
1016				lhs, rhs := []ir.Node{as.X}, []ir.Node{as.Y}
1017				transformAssign(as, lhs, rhs)
1018				as.X, as.Y = lhs[0], rhs[0]
1019			}
1020
1021		case ir.OASOP:
1022			as := m.(*ir.AssignOpStmt)
1023			transformCheckAssign(as, as.X)
1024
1025		case ir.ORETURN:
1026			transformReturn(m.(*ir.ReturnStmt))
1027
1028		case ir.OSEND:
1029			transformSend(m.(*ir.SendStmt))
1030
1031		case ir.OSELECT:
1032			transformSelect(m.(*ir.SelectStmt))
1033
1034		case ir.OCOMPLIT:
1035			transformCompLit(m.(*ir.CompLitExpr))
1036
1037		case ir.OADDR:
1038			transformAddr(m.(*ir.AddrExpr))
1039
1040		case ir.OLITERAL:
1041			t := m.Type()
1042			if t != x.Type() {
1043				// types2 will give us a constant with a type T,
1044				// if an untyped constant is used with another
1045				// operand of type T (in a provably correct way).
1046				// When we substitute in the type args during
1047				// stenciling, we now know the real type of the
1048				// constant. We may then need to change the
1049				// BasicLit.val to be the correct type (e.g.
1050				// convert an int64Val constant to a floatVal
1051				// constant).
1052				m.SetType(types.UntypedInt) // use any untyped type for DefaultLit to work
1053				m = typecheck.DefaultLit(m, t)
1054			}
1055
1056		case ir.OXDOT:
1057			// Finish the transformation of an OXDOT, unless this was a
1058			// bound call (a direct call on a type param). A bound call
1059			// will be transformed during the dictPass. Otherwise, m
1060			// will be transformed to an OMETHVALUE node. It will be
1061			// transformed to an ODOTMETH or ODOTINTER node if we find in
1062			// the OCALL case below that the method value is actually
1063			// called.
1064			mse := m.(*ir.SelectorExpr)
1065			if src := mse.X.Type(); !src.IsShape() {
1066				transformDot(mse, false)
1067			}
1068
1069		case ir.OCALL:
1070			call := m.(*ir.CallExpr)
1071			switch call.X.Op() {
1072			case ir.OTYPE:
1073				// Transform the conversion, now that we know the
1074				// type argument.
1075				m = transformConvCall(call)
1076				// CONVIFACE transformation was already done in noder2
1077				assert(m.Op() != ir.OCONVIFACE)
1078
1079			case ir.OMETHVALUE, ir.OMETHEXPR:
1080				// Redo the transformation of OXDOT, now that we
1081				// know the method value is being called. Then
1082				// transform the call.
1083				call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
1084				transformDot(call.X.(*ir.SelectorExpr), true)
1085				transformCall(call)
1086
1087			case ir.ODOT, ir.ODOTPTR:
1088				// An OXDOT for a generic receiver was resolved to
1089				// an access to a field which has a function
1090				// value. Transform the call to that function, now
1091				// that the OXDOT was resolved.
1092				transformCall(call)
1093
1094			case ir.ONAME:
1095				name := call.X.Name()
1096				if name.BuiltinOp != ir.OXXX {
1097					switch name.BuiltinOp {
1098					case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.ODELETE, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
1099						// Transform these builtins now that we
1100						// know the type of the args.
1101						m = transformBuiltin(call)
1102					default:
1103						base.FatalfAt(call.Pos(), "Unexpected builtin op")
1104					}
1105				} else {
1106					// This is the case of a function value that was a
1107					// type parameter (implied to be a function via a
1108					// structural constraint) which is now resolved.
1109					transformCall(call)
1110				}
1111
1112			case ir.OFUNCINST:
1113				// A call with an OFUNCINST will get transformed
1114				// in stencil() once we have created & attached the
1115				// instantiation to be called.
1116				// We must transform the arguments of the call now, though,
1117				// so that any needed CONVIFACE nodes are exposed,
1118				// so the dictionary format is correct.
1119				transformEarlyCall(call)
1120
1121			case ir.OXDOT:
1122				// This is the case of a bound call on a typeparam,
1123				// which will be handled in the dictPass.
1124				// As with OFUNCINST, we must transform the arguments of the call now,
1125				// so any needed CONVIFACE nodes are exposed.
1126				transformEarlyCall(call)
1127
1128			case ir.ODOTTYPE, ir.ODOTTYPE2:
1129				// These are DOTTYPEs that could get transformed into
1130				// ODYNAMIC DOTTYPEs by the dict pass.
1131
1132			default:
1133				// Transform a call for all other values of
1134				// call.X.Op() that don't require any special
1135				// handling.
1136				transformCall(call)
1137
1138			}
1139
1140		case ir.OCLOSURE:
1141			// We're going to create a new closure from scratch, so clear m
1142			// to avoid using the ir.Copy by accident until we reassign it.
1143			m = nil
1144
1145			x := x.(*ir.ClosureExpr)
1146			// Need to duplicate x.Func.Nname, x.Func.Dcl, x.Func.ClosureVars, and
1147			// x.Func.Body.
1148			oldfn := x.Func
1149			newfn := ir.NewClosureFunc(oldfn.Pos(), subst.newf != nil)
1150			ir.NameClosure(newfn.OClosure, subst.newf)
1151
1152			saveNewf := subst.newf
1153			ir.CurFunc = newfn
1154			subst.newf = newfn
1155			newfn.Dcl = subst.namelist(oldfn.Dcl)
1156
1157			// Make a closure variable for the dictionary of the
1158			// containing function.
1159			cdict := ir.CaptureName(oldfn.Pos(), newfn, subst.info.dictParam)
1160			typed(types.Types[types.TUINTPTR], cdict)
1161			ir.FinishCaptureNames(oldfn.Pos(), saveNewf, newfn)
1162			newfn.ClosureVars = append(newfn.ClosureVars, subst.namelist(oldfn.ClosureVars)...)
1163
1164			// Copy that closure variable to a local one.
1165			// Note: this allows the dictionary to be captured by child closures.
1166			// See issue 47723.
1167			ldict := ir.NewNameAt(x.Pos(), newfn.Sym().Pkg.Lookup(typecheck.LocalDictName))
1168			typed(types.Types[types.TUINTPTR], ldict)
1169			ldict.Class = ir.PAUTO
1170			ldict.Curfn = newfn
1171			newfn.Dcl = append(newfn.Dcl, ldict)
1172			as := ir.NewAssignStmt(x.Pos(), ldict, cdict)
1173			as.SetTypecheck(1)
1174			newfn.Body.Append(as)
1175
1176			// Create inst info for the instantiated closure. The dict
1177			// param is the closure variable for the dictionary of the
1178			// outer function. Since the dictionary is shared, use the
1179			// same dictInfo.
1180			cinfo := &instInfo{
1181				fun:       newfn,
1182				dictParam: ldict,
1183				dictInfo:  subst.info.dictInfo,
1184			}
1185			subst.g.instInfoMap[newfn.Nname.Sym()] = cinfo
1186
1187			typed(subst.ts.Typ(oldfn.Nname.Type()), newfn.Nname)
1188			typed(newfn.Nname.Type(), newfn.OClosure)
1189			newfn.SetTypecheck(1)
1190
1191			outerinfo := subst.info
1192			subst.info = cinfo
1193			// Make sure type of closure function is set before doing body.
1194			newfn.Body.Append(subst.list(oldfn.Body)...)
1195			subst.info = outerinfo
1196			subst.newf = saveNewf
1197			ir.CurFunc = saveNewf
1198
1199			m = ir.UseClosure(newfn.OClosure, typecheck.Target)
1200			subst.g.newInsts = append(subst.g.newInsts, m.(*ir.ClosureExpr).Func)
1201			m.(*ir.ClosureExpr).SetInit(subst.list(x.Init()))
1202
1203		}
1204		return m
1205	}
1206
1207	return edit(n)
1208}
1209
1210// dictPass takes a function instantiation and does the transformations on the
1211// operations that need to make use of the dictionary param.
1212func (g *genInst) dictPass(info *instInfo) {
1213	savef := ir.CurFunc
1214	ir.CurFunc = info.fun
1215
1216	var edit func(ir.Node) ir.Node
1217	edit = func(m ir.Node) ir.Node {
1218		ir.EditChildren(m, edit)
1219
1220		switch m.Op() {
1221		case ir.OCLOSURE:
1222			newf := m.(*ir.ClosureExpr).Func
1223			ir.CurFunc = newf
1224			outerinfo := info
1225			info = g.instInfoMap[newf.Nname.Sym()]
1226
1227			body := newf.Body
1228			for i, n := range body {
1229				body[i] = edit(n)
1230			}
1231
1232			info = outerinfo
1233			ir.CurFunc = info.fun
1234
1235		case ir.OXDOT:
1236			mse := m.(*ir.SelectorExpr)
1237			src := mse.X.Type()
1238			assert(src.IsShape())
1239
1240			// The only dot on a shape type value are methods.
1241			if mse.X.Op() == ir.OTYPE {
1242				// Method expression T.M
1243				m = g.buildClosure2(info, m)
1244				// No need for transformDot - buildClosure2 has already
1245				// transformed to OCALLINTER/ODOTINTER.
1246			} else {
1247				// Implement x.M as a conversion-to-bound-interface
1248				//  1) convert x to the bound interface
1249				//  2) call M on that interface
1250				dst := info.dictInfo.shapeToBound[m.(*ir.SelectorExpr).X.Type()]
1251				if src.IsInterface() {
1252					// If type arg is an interface (unusual case),
1253					// we do a type assert to the type bound.
1254					mse.X = assertToBound(info, info.dictParam, m.Pos(), mse.X, dst)
1255				} else {
1256					mse.X = convertUsingDictionary(info, info.dictParam, m.Pos(), mse.X, m, dst)
1257				}
1258				transformDot(mse, false)
1259			}
1260		case ir.OCALL:
1261			call := m.(*ir.CallExpr)
1262			op := call.X.Op()
1263			if op == ir.OMETHVALUE {
1264				// Redo the transformation of OXDOT, now that we
1265				// know the method value is being called.
1266				call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
1267				transformDot(call.X.(*ir.SelectorExpr), true)
1268			}
1269			transformCall(call)
1270
1271		case ir.OCONVIFACE:
1272			if m.Type().IsEmptyInterface() && m.(*ir.ConvExpr).X.Type().IsEmptyInterface() {
1273				// Was T->interface{}, after stenciling it is now interface{}->interface{}.
1274				// No longer need the conversion. See issue 48276.
1275				m.(*ir.ConvExpr).SetOp(ir.OCONVNOP)
1276				break
1277			}
1278			mce := m.(*ir.ConvExpr)
1279			// Note: x's argument is still typed as a type parameter.
1280			// m's argument now has an instantiated type.
1281			if mce.X.Type().HasShape() || (mce.X.Type().IsInterface() && m.Type().HasShape()) {
1282				m = convertUsingDictionary(info, info.dictParam, m.Pos(), m.(*ir.ConvExpr).X, m, m.Type())
1283			}
1284		case ir.ODOTTYPE, ir.ODOTTYPE2:
1285			if !m.Type().HasShape() {
1286				break
1287			}
1288			dt := m.(*ir.TypeAssertExpr)
1289			var rt ir.Node
1290			if dt.Type().IsInterface() || dt.X.Type().IsEmptyInterface() {
1291				ix := findDictType(info, m.Type())
1292				assert(ix >= 0)
1293				rt = getDictionaryType(info, info.dictParam, dt.Pos(), ix)
1294			} else {
1295				// nonempty interface to noninterface. Need an itab.
1296				ix := -1
1297				for i, ic := range info.dictInfo.itabConvs {
1298					if ic == m {
1299						ix = info.dictInfo.startItabConv + i
1300						break
1301					}
1302				}
1303				assert(ix >= 0)
1304				rt = getDictionaryEntry(dt.Pos(), info.dictParam, ix, info.dictInfo.dictLen)
1305			}
1306			op := ir.ODYNAMICDOTTYPE
1307			if m.Op() == ir.ODOTTYPE2 {
1308				op = ir.ODYNAMICDOTTYPE2
1309			}
1310			m = ir.NewDynamicTypeAssertExpr(dt.Pos(), op, dt.X, rt)
1311			m.SetType(dt.Type())
1312			m.SetTypecheck(1)
1313		case ir.OCASE:
1314			if _, ok := m.(*ir.CommClause); ok {
1315				// This is not a type switch. TODO: Should we use an OSWITCH case here instead of OCASE?
1316				break
1317			}
1318			m := m.(*ir.CaseClause)
1319			for i, c := range m.List {
1320				if c.Op() == ir.OTYPE && c.Type().HasShape() {
1321					// Use a *runtime._type for the dynamic type.
1322					ix := findDictType(info, m.List[i].Type())
1323					assert(ix >= 0)
1324					dt := ir.NewDynamicType(c.Pos(), getDictionaryEntry(c.Pos(), info.dictParam, ix, info.dictInfo.dictLen))
1325
1326					// For type switch from nonempty interfaces to non-interfaces, we need an itab as well.
1327					if !m.List[i].Type().IsInterface() {
1328						if _, ok := info.dictInfo.type2switchType[m.List[i]]; ok {
1329							// Type switch from nonempty interface. We need a *runtime.itab
1330							// for the dynamic type.
1331							ix := -1
1332							for j, ic := range info.dictInfo.itabConvs {
1333								if ic == m.List[i] {
1334									ix = info.dictInfo.startItabConv + j
1335									break
1336								}
1337							}
1338							assert(ix >= 0)
1339							dt.ITab = getDictionaryEntry(c.Pos(), info.dictParam, ix, info.dictInfo.dictLen)
1340						}
1341					}
1342					typed(m.List[i].Type(), dt)
1343					m.List[i] = dt
1344				}
1345			}
1346
1347		}
1348		return m
1349	}
1350	edit(info.fun)
1351	ir.CurFunc = savef
1352}
1353
1354// findDictType looks for type t in the typeparams or derived types in the generic
1355// function info.gfInfo. This will indicate the dictionary entry with the
1356// correct concrete type for the associated instantiated function.
1357func findDictType(info *instInfo, t *types.Type) int {
1358	for i, dt := range info.dictInfo.shapeParams {
1359		if dt == t {
1360			return i
1361		}
1362	}
1363	for i, dt := range info.dictInfo.derivedTypes {
1364		if types.IdenticalStrict(dt, t) {
1365			return i + len(info.dictInfo.shapeParams)
1366		}
1367	}
1368	return -1
1369}
1370
1371// convertUsingDictionary converts instantiated value v (type v.Type()) to an interface
1372// type dst, by returning a new set of nodes that make use of a dictionary entry. in is the
1373// instantiated node of the CONVIFACE node or XDOT node (for a bound method call) that is causing the
1374// conversion.
1375func convertUsingDictionary(info *instInfo, dictParam *ir.Name, pos src.XPos, v ir.Node, in ir.Node, dst *types.Type) ir.Node {
1376	assert(v.Type().HasShape() || v.Type().IsInterface() && in.Type().HasShape())
1377	assert(dst.IsInterface())
1378
1379	if v.Type().IsInterface() {
1380		// Converting from an interface. The shape-ness of the source doesn't really matter, as
1381		// we'll be using the concrete type from the first interface word.
1382		if dst.IsEmptyInterface() {
1383			// Converting I2E. OCONVIFACE does that for us, and doesn't depend
1384			// on what the empty interface was instantiated with. No dictionary entry needed.
1385			v = ir.NewConvExpr(pos, ir.OCONVIFACE, dst, v)
1386			v.SetTypecheck(1)
1387			return v
1388		}
1389		if !in.Type().HasShape() {
1390			// Regular OCONVIFACE works if the destination isn't parameterized.
1391			v = ir.NewConvExpr(pos, ir.OCONVIFACE, dst, v)
1392			v.SetTypecheck(1)
1393			return v
1394		}
1395
1396		// We get the destination interface type from the dictionary and the concrete
1397		// type from the argument's itab. Call runtime.convI2I to get the new itab.
1398		tmp := typecheck.Temp(v.Type())
1399		as := ir.NewAssignStmt(pos, tmp, v)
1400		as.SetTypecheck(1)
1401		itab := ir.NewUnaryExpr(pos, ir.OITAB, tmp)
1402		typed(types.Types[types.TUINTPTR].PtrTo(), itab)
1403		idata := ir.NewUnaryExpr(pos, ir.OIDATA, tmp)
1404		typed(types.Types[types.TUNSAFEPTR], idata)
1405
1406		fn := typecheck.LookupRuntime("convI2I")
1407		fn.SetTypecheck(1)
1408		types.CalcSize(fn.Type())
1409		call := ir.NewCallExpr(pos, ir.OCALLFUNC, fn, nil)
1410		typed(types.Types[types.TUINT8].PtrTo(), call)
1411		ix := findDictType(info, in.Type())
1412		assert(ix >= 0)
1413		inter := getDictionaryType(info, dictParam, pos, ix)
1414		call.Args = []ir.Node{inter, itab}
1415		i := ir.NewBinaryExpr(pos, ir.OEFACE, call, idata)
1416		typed(dst, i)
1417		i.PtrInit().Append(as)
1418		return i
1419	}
1420
1421	var rt ir.Node
1422	if !dst.IsEmptyInterface() {
1423		// We should have an itab entry in the dictionary. Using this itab
1424		// will be more efficient than converting to an empty interface first
1425		// and then type asserting to dst.
1426		ix := -1
1427		for i, ic := range info.dictInfo.itabConvs {
1428			if ic == in {
1429				ix = info.dictInfo.startItabConv + i
1430				break
1431			}
1432		}
1433		assert(ix >= 0)
1434		rt = getDictionaryEntry(pos, dictParam, ix, info.dictInfo.dictLen)
1435	} else {
1436		ix := findDictType(info, v.Type())
1437		assert(ix >= 0)
1438		// Load the actual runtime._type of the type parameter from the dictionary.
1439		rt = getDictionaryType(info, dictParam, pos, ix)
1440	}
1441
1442	// Figure out what the data field of the interface will be.
1443	data := ir.NewConvExpr(pos, ir.OCONVIDATA, nil, v)
1444	typed(types.Types[types.TUNSAFEPTR], data)
1445
1446	// Build an interface from the type and data parts.
1447	var i ir.Node = ir.NewBinaryExpr(pos, ir.OEFACE, rt, data)
1448	typed(dst, i)
1449	return i
1450}
1451
1452func (subst *subster) namelist(l []*ir.Name) []*ir.Name {
1453	s := make([]*ir.Name, len(l))
1454	for i, n := range l {
1455		s[i] = subst.localvar(n)
1456	}
1457	return s
1458}
1459
1460func (subst *subster) list(l []ir.Node) []ir.Node {
1461	s := make([]ir.Node, len(l))
1462	for i, n := range l {
1463		s[i] = subst.node(n)
1464	}
1465	return s
1466}
1467
1468// fields sets the Nname field for the Field nodes inside a type signature, based
1469// on the corresponding in/out parameters in dcl. It depends on the in and out
1470// parameters being in order in dcl.
1471func (subst *subster) fields(class ir.Class, oldfields []*types.Field, dcl []*ir.Name) []*types.Field {
1472	// Find the starting index in dcl of declarations of the class (either
1473	// PPARAM or PPARAMOUT).
1474	var i int
1475	for i = range dcl {
1476		if dcl[i].Class == class {
1477			break
1478		}
1479	}
1480
1481	// Create newfields nodes that are copies of the oldfields nodes, but
1482	// with substitution for any type params, and with Nname set to be the node in
1483	// Dcl for the corresponding PPARAM or PPARAMOUT.
1484	newfields := make([]*types.Field, len(oldfields))
1485	for j := range oldfields {
1486		newfields[j] = oldfields[j].Copy()
1487		newfields[j].Type = subst.ts.Typ(oldfields[j].Type)
1488		// A PPARAM field will be missing from dcl if its name is
1489		// unspecified or specified as "_". So, we compare the dcl sym
1490		// with the field sym (or sym of the field's Nname node). (Unnamed
1491		// results still have a name like ~r2 in their Nname node.) If
1492		// they don't match, this dcl (if there is one left) must apply to
1493		// a later field.
1494		if i < len(dcl) && (dcl[i].Sym() == oldfields[j].Sym ||
1495			(oldfields[j].Nname != nil && dcl[i].Sym() == oldfields[j].Nname.Sym())) {
1496			newfields[j].Nname = dcl[i]
1497			i++
1498		}
1499	}
1500	return newfields
1501}
1502
1503// deref does a single deref of type t, if it is a pointer type.
1504func deref(t *types.Type) *types.Type {
1505	if t.IsPtr() {
1506		return t.Elem()
1507	}
1508	return t
1509}
1510
1511// markTypeUsed marks type t as used in order to help avoid dead-code elimination of
1512// needed methods.
1513func markTypeUsed(t *types.Type, lsym *obj.LSym) {
1514	if t.IsInterface() {
1515		return
1516	}
1517	// TODO: This is somewhat overkill, we really only need it
1518	// for types that are put into interfaces.
1519	// Note: this relocation is also used in cmd/link/internal/ld/dwarf.go
1520	reflectdata.MarkTypeUsedInInterface(t, lsym)
1521}
1522
1523// getDictionarySym returns the dictionary for the named generic function gf, which
1524// is instantiated with the type arguments targs.
1525func (g *genInst) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool) *types.Sym {
1526	if len(targs) == 0 {
1527		base.Fatalf("%s should have type arguments", gf.Sym().Name)
1528	}
1529
1530	// Enforce that only concrete types can make it to here.
1531	for _, t := range targs {
1532		if t.HasShape() {
1533			panic(fmt.Sprintf("shape %+v in dictionary for %s", t, gf.Sym().Name))
1534		}
1535	}
1536
1537	// Get a symbol representing the dictionary.
1538	sym := typecheck.MakeDictSym(gf.Sym(), targs, isMeth)
1539
1540	// Initialize the dictionary, if we haven't yet already.
1541	lsym := sym.Linksym()
1542	if len(lsym.P) > 0 {
1543		// We already started creating this dictionary and its lsym.
1544		return sym
1545	}
1546
1547	infoPrint("=== Creating dictionary %v\n", sym.Name)
1548	off := 0
1549	// Emit an entry for each targ (concrete type or gcshape).
1550	for _, t := range targs {
1551		infoPrint(" * %v\n", t)
1552		s := reflectdata.TypeLinksym(t)
1553		off = objw.SymPtr(lsym, off, s, 0)
1554		markTypeUsed(t, lsym)
1555	}
1556
1557	instInfo := g.getInstantiation(gf, targs, isMeth)
1558	info := instInfo.dictInfo
1559
1560	subst := typecheck.Tsubster{
1561		Tparams: info.shapeParams,
1562		Targs:   targs,
1563	}
1564	// Emit an entry for each derived type (after substituting targs)
1565	for _, t := range info.derivedTypes {
1566		ts := subst.Typ(t)
1567		infoPrint(" - %v\n", ts)
1568		s := reflectdata.TypeLinksym(ts)
1569		off = objw.SymPtr(lsym, off, s, 0)
1570		markTypeUsed(ts, lsym)
1571	}
1572	// Emit an entry for each subdictionary (after substituting targs)
1573	for _, n := range info.subDictCalls {
1574		var sym *types.Sym
1575		switch n.Op() {
1576		case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH:
1577			call := n.(*ir.CallExpr)
1578			if call.X.Op() == ir.OXDOT || call.X.Op() == ir.ODOTMETH {
1579				var nameNode *ir.Name
1580				se := call.X.(*ir.SelectorExpr)
1581				if se.X.Type().IsShape() {
1582					// This is a method call enabled by a type bound.
1583
1584					// We need this extra check for method expressions,
1585					// which don't add in the implicit XDOTs.
1586					tmpse := ir.NewSelectorExpr(src.NoXPos, ir.OXDOT, se.X, se.Sel)
1587					tmpse = typecheck.AddImplicitDots(tmpse)
1588					tparam := tmpse.X.Type()
1589					if !tparam.IsShape() {
1590						// The method expression is not
1591						// really on a typeparam.
1592						break
1593					}
1594					ix := -1
1595					for i, shape := range info.shapeParams {
1596						if shape == tparam {
1597							ix = i
1598							break
1599						}
1600					}
1601					assert(ix >= 0)
1602					recvType := targs[ix]
1603					if recvType.IsInterface() || len(recvType.RParams()) == 0 {
1604						// No sub-dictionary entry is
1605						// actually needed, since the
1606						// type arg is not an
1607						// instantiated type that
1608						// will have generic methods.
1609						break
1610					}
1611					// This is a method call for an
1612					// instantiated type, so we need a
1613					// sub-dictionary.
1614					targs := recvType.RParams()
1615					genRecvType := recvType.OrigSym().Def.Type()
1616					nameNode = typecheck.Lookdot1(call.X, se.Sel, genRecvType, genRecvType.Methods(), 1).Nname.(*ir.Name)
1617					sym = g.getDictionarySym(nameNode, targs, true)
1618				} else {
1619					// This is the case of a normal
1620					// method call on a generic type.
1621					recvType := deref(call.X.(*ir.SelectorExpr).X.Type())
1622					genRecvType := recvType.OrigSym().Def.Type()
1623					nameNode = typecheck.Lookdot1(call.X, se.Sel, genRecvType, genRecvType.Methods(), 1).Nname.(*ir.Name)
1624					subtargs := recvType.RParams()
1625					s2targs := make([]*types.Type, len(subtargs))
1626					for i, t := range subtargs {
1627						s2targs[i] = subst.Typ(t)
1628					}
1629					sym = g.getDictionarySym(nameNode, s2targs, true)
1630				}
1631			} else {
1632				inst := call.X.(*ir.InstExpr)
1633				var nameNode *ir.Name
1634				var meth *ir.SelectorExpr
1635				var isMeth bool
1636				if meth, isMeth = inst.X.(*ir.SelectorExpr); isMeth {
1637					nameNode = meth.Selection.Nname.(*ir.Name)
1638				} else {
1639					nameNode = inst.X.(*ir.Name)
1640				}
1641				subtargs := typecheck.TypesOf(inst.Targs)
1642				for i, t := range subtargs {
1643					subtargs[i] = subst.Typ(t)
1644				}
1645				sym = g.getDictionarySym(nameNode, subtargs, isMeth)
1646			}
1647
1648		case ir.OFUNCINST:
1649			inst := n.(*ir.InstExpr)
1650			nameNode := inst.X.(*ir.Name)
1651			subtargs := typecheck.TypesOf(inst.Targs)
1652			for i, t := range subtargs {
1653				subtargs[i] = subst.Typ(t)
1654			}
1655			sym = g.getDictionarySym(nameNode, subtargs, false)
1656
1657		case ir.OXDOT, ir.OMETHEXPR, ir.OMETHVALUE:
1658			selExpr := n.(*ir.SelectorExpr)
1659			recvType := deref(selExpr.Selection.Type.Recv().Type)
1660			genRecvType := recvType.OrigSym().Def.Type()
1661			subtargs := recvType.RParams()
1662			s2targs := make([]*types.Type, len(subtargs))
1663			for i, t := range subtargs {
1664				s2targs[i] = subst.Typ(t)
1665			}
1666			nameNode := typecheck.Lookdot1(selExpr, selExpr.Sel, genRecvType, genRecvType.Methods(), 1).Nname.(*ir.Name)
1667			sym = g.getDictionarySym(nameNode, s2targs, true)
1668
1669		default:
1670			assert(false)
1671		}
1672
1673		if sym == nil {
1674			// Unused sub-dictionary entry, just emit 0.
1675			off = objw.Uintptr(lsym, off, 0)
1676			infoPrint(" - Unused subdict entry\n")
1677		} else {
1678			off = objw.SymPtr(lsym, off, sym.Linksym(), 0)
1679			infoPrint(" - Subdict %v\n", sym.Name)
1680		}
1681	}
1682
1683	g.instantiateMethods()
1684	delay := &delayInfo{
1685		gf:     gf,
1686		targs:  targs,
1687		sym:    sym,
1688		off:    off,
1689		isMeth: isMeth,
1690	}
1691	g.dictSymsToFinalize = append(g.dictSymsToFinalize, delay)
1692	return sym
1693}
1694
1695// finalizeSyms finishes up all dictionaries on g.dictSymsToFinalize, by writing out
1696// any needed LSyms for itabs. The itab lsyms create wrappers which need various
1697// dictionaries and method instantiations to be complete, so, to avoid recursive
1698// dependencies, we finalize the itab lsyms only after all dictionaries syms and
1699// instantiations have been created.
1700func (g *genInst) finalizeSyms() {
1701	for _, d := range g.dictSymsToFinalize {
1702		infoPrint("=== Finalizing dictionary %s\n", d.sym.Name)
1703
1704		lsym := d.sym.Linksym()
1705		instInfo := g.getInstantiation(d.gf, d.targs, d.isMeth)
1706		info := instInfo.dictInfo
1707
1708		subst := typecheck.Tsubster{
1709			Tparams: info.shapeParams,
1710			Targs:   d.targs,
1711		}
1712
1713		// Emit an entry for each itab
1714		for _, n := range info.itabConvs {
1715			var srctype, dsttype *types.Type
1716			switch n.Op() {
1717			case ir.OXDOT, ir.OMETHVALUE:
1718				se := n.(*ir.SelectorExpr)
1719				srctype = subst.Typ(se.X.Type())
1720				dsttype = subst.Typ(info.shapeToBound[se.X.Type()])
1721			case ir.ODOTTYPE, ir.ODOTTYPE2:
1722				srctype = subst.Typ(n.(*ir.TypeAssertExpr).Type())
1723				dsttype = subst.Typ(n.(*ir.TypeAssertExpr).X.Type())
1724			case ir.OCONVIFACE:
1725				srctype = subst.Typ(n.(*ir.ConvExpr).X.Type())
1726				dsttype = subst.Typ(n.Type())
1727			case ir.OTYPE:
1728				srctype = subst.Typ(n.Type())
1729				dsttype = subst.Typ(info.type2switchType[n])
1730			default:
1731				base.Fatalf("itab entry with unknown op %s", n.Op())
1732			}
1733			if srctype.IsInterface() || dsttype.IsEmptyInterface() {
1734				// No itab is wanted if src type is an interface. We
1735				// will use a type assert instead.
1736				d.off = objw.Uintptr(lsym, d.off, 0)
1737				infoPrint(" + Unused itab entry for %v\n", srctype)
1738			} else {
1739				// Make sure all new fully-instantiated types have
1740				// their methods created before generating any itabs.
1741				g.instantiateMethods()
1742				itabLsym := reflectdata.ITabLsym(srctype, dsttype)
1743				d.off = objw.SymPtr(lsym, d.off, itabLsym, 0)
1744				infoPrint(" + Itab for (%v,%v)\n", srctype, dsttype)
1745			}
1746		}
1747
1748		objw.Global(lsym, int32(d.off), obj.DUPOK|obj.RODATA)
1749		infoPrint("=== Finalized dictionary %s\n", d.sym.Name)
1750	}
1751	g.dictSymsToFinalize = nil
1752}
1753
1754func (g *genInst) getDictionaryValue(pos src.XPos, gf *ir.Name, targs []*types.Type, isMeth bool) ir.Node {
1755	sym := g.getDictionarySym(gf, targs, isMeth)
1756
1757	// Make (or reuse) a node referencing the dictionary symbol.
1758	var n *ir.Name
1759	if sym.Def != nil {
1760		n = sym.Def.(*ir.Name)
1761	} else {
1762		// We set the position of a static dictionary to be the position of
1763		// one of its uses.
1764		n = ir.NewNameAt(pos, sym)
1765		n.Curfn = ir.CurFunc
1766		n.SetType(types.Types[types.TUINTPTR]) // should probably be [...]uintptr, but doesn't really matter
1767		n.SetTypecheck(1)
1768		n.Class = ir.PEXTERN
1769		sym.Def = n
1770	}
1771
1772	// Return the address of the dictionary.  Addr node gets position that was passed in.
1773	np := typecheck.NodAddrAt(pos, n)
1774	// Note: treat dictionary pointers as uintptrs, so they aren't pointers
1775	// with respect to GC. That saves on stack scanning work, write barriers, etc.
1776	// We can get away with it because dictionaries are global variables.
1777	// TODO: use a cast, or is typing directly ok?
1778	np.SetType(types.Types[types.TUINTPTR])
1779	np.SetTypecheck(1)
1780	return np
1781}
1782
1783// hasShapeNodes returns true if the type of any node in targs has a shape.
1784func hasShapeNodes(targs []ir.Node) bool {
1785	for _, n := range targs {
1786		if n.Type().HasShape() {
1787			return true
1788		}
1789	}
1790	return false
1791}
1792
1793// hasShapeTypes returns true if any type in targs has a shape.
1794func hasShapeTypes(targs []*types.Type) bool {
1795	for _, t := range targs {
1796		if t.HasShape() {
1797			return true
1798		}
1799	}
1800	return false
1801}
1802
1803// getInstInfo get the dictionary format for a function instantiation- type params, derived
1804// types, and needed subdictionaries and itabs.
1805func (g *genInst) getInstInfo(st *ir.Func, shapes []*types.Type, instInfo *instInfo) {
1806	info := instInfo.dictInfo
1807	info.shapeParams = shapes
1808
1809	for _, t := range info.shapeParams {
1810		b := info.shapeToBound[t]
1811		if b.HasShape() {
1812			// If a type bound is parameterized (unusual case), then we
1813			// may need its derived type to do a type assert when doing a
1814			// bound call for a type arg that is an interface.
1815			addType(info, nil, b)
1816		}
1817	}
1818
1819	for _, n := range st.Dcl {
1820		addType(info, n, n.Type())
1821		n.DictIndex = uint16(findDictType(instInfo, n.Type()) + 1)
1822	}
1823
1824	if infoPrintMode {
1825		fmt.Printf(">>> InstInfo for %v\n", st)
1826		for _, t := range info.shapeParams {
1827			fmt.Printf("  Typeparam %v\n", t)
1828		}
1829	}
1830
1831	// Map to remember when we have seen an instantiated function value or method
1832	// expression/value as part of a call, so we can determine when we encounter
1833	// an uncalled function value or method expression/value.
1834	callMap := make(map[ir.Node]bool)
1835
1836	var visitFunc func(ir.Node)
1837	visitFunc = func(n ir.Node) {
1838		switch n.Op() {
1839		case ir.OFUNCINST:
1840			if !callMap[n] && hasShapeNodes(n.(*ir.InstExpr).Targs) {
1841				infoPrint("  Closure&subdictionary required at generic function value %v\n", n.(*ir.InstExpr).X)
1842				info.subDictCalls = append(info.subDictCalls, n)
1843			}
1844		case ir.OMETHEXPR, ir.OMETHVALUE:
1845			if !callMap[n] && !types.IsInterfaceMethod(n.(*ir.SelectorExpr).Selection.Type) &&
1846				len(deref(n.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
1847				hasShapeTypes(deref(n.(*ir.SelectorExpr).X.Type()).RParams()) {
1848				if n.(*ir.SelectorExpr).X.Op() == ir.OTYPE {
1849					infoPrint("  Closure&subdictionary required at generic meth expr %v\n", n)
1850				} else {
1851					infoPrint("  Closure&subdictionary required at generic meth value %v\n", n)
1852				}
1853				info.subDictCalls = append(info.subDictCalls, n)
1854			}
1855		case ir.OCALL:
1856			ce := n.(*ir.CallExpr)
1857			if ce.X.Op() == ir.OFUNCINST {
1858				callMap[ce.X] = true
1859				if hasShapeNodes(ce.X.(*ir.InstExpr).Targs) {
1860					infoPrint("  Subdictionary at generic function/method call: %v - %v\n", ce.X.(*ir.InstExpr).X, n)
1861					info.subDictCalls = append(info.subDictCalls, n)
1862				}
1863			}
1864			if ce.X.Op() == ir.OXDOT &&
1865				isShapeDeref(ce.X.(*ir.SelectorExpr).X.Type()) {
1866				callMap[ce.X] = true
1867				infoPrint("  Optional subdictionary at generic bound call: %v\n", n)
1868				info.subDictCalls = append(info.subDictCalls, n)
1869			}
1870		case ir.OCALLMETH:
1871			ce := n.(*ir.CallExpr)
1872			if ce.X.Op() == ir.ODOTMETH &&
1873				len(deref(ce.X.(*ir.SelectorExpr).X.Type()).RParams()) > 0 {
1874				callMap[ce.X] = true
1875				if hasShapeTypes(deref(ce.X.(*ir.SelectorExpr).X.Type()).RParams()) {
1876					infoPrint("  Subdictionary at generic method call: %v\n", n)
1877					info.subDictCalls = append(info.subDictCalls, n)
1878				}
1879			}
1880		case ir.OCONVIFACE:
1881			if n.Type().IsInterface() && !n.Type().IsEmptyInterface() &&
1882				n.(*ir.ConvExpr).X.Type().HasShape() {
1883				infoPrint("  Itab for interface conv: %v\n", n)
1884				info.itabConvs = append(info.itabConvs, n)
1885			}
1886		case ir.OXDOT:
1887			if n.(*ir.SelectorExpr).X.Type().IsShape() {
1888				infoPrint("  Itab for bound call: %v\n", n)
1889				info.itabConvs = append(info.itabConvs, n)
1890			}
1891		case ir.ODOTTYPE, ir.ODOTTYPE2:
1892			if !n.(*ir.TypeAssertExpr).Type().IsInterface() && !n.(*ir.TypeAssertExpr).X.Type().IsEmptyInterface() {
1893				infoPrint("  Itab for dot type: %v\n", n)
1894				info.itabConvs = append(info.itabConvs, n)
1895			}
1896		case ir.OCLOSURE:
1897			// Visit the closure body and add all relevant entries to the
1898			// dictionary of the outer function (closure will just use
1899			// the dictionary of the outer function).
1900			cfunc := n.(*ir.ClosureExpr).Func
1901			for _, n1 := range cfunc.Body {
1902				ir.Visit(n1, visitFunc)
1903			}
1904			for _, n := range cfunc.Dcl {
1905				n.DictIndex = uint16(findDictType(instInfo, n.Type()) + 1)
1906			}
1907		case ir.OSWITCH:
1908			ss := n.(*ir.SwitchStmt)
1909			if ss.Tag != nil && ss.Tag.Op() == ir.OTYPESW &&
1910				!ss.Tag.(*ir.TypeSwitchGuard).X.Type().IsEmptyInterface() {
1911				for _, cc := range ss.Cases {
1912					for _, c := range cc.List {
1913						if c.Op() == ir.OTYPE && c.Type().HasShape() {
1914							// Type switch from a non-empty interface - might need an itab.
1915							infoPrint("  Itab for type switch: %v\n", c)
1916							info.itabConvs = append(info.itabConvs, c)
1917							if info.type2switchType == nil {
1918								info.type2switchType = map[ir.Node]*types.Type{}
1919							}
1920							info.type2switchType[c] = ss.Tag.(*ir.TypeSwitchGuard).X.Type()
1921						}
1922					}
1923				}
1924			}
1925		}
1926		addType(info, n, n.Type())
1927	}
1928
1929	for _, stmt := range st.Body {
1930		ir.Visit(stmt, visitFunc)
1931	}
1932	if infoPrintMode {
1933		for _, t := range info.derivedTypes {
1934			fmt.Printf("  Derived type %v\n", t)
1935		}
1936		fmt.Printf(">>> Done Instinfo\n")
1937	}
1938	info.startSubDict = len(info.shapeParams) + len(info.derivedTypes)
1939	info.startItabConv = len(info.shapeParams) + len(info.derivedTypes) + len(info.subDictCalls)
1940	info.dictLen = len(info.shapeParams) + len(info.derivedTypes) + len(info.subDictCalls) + len(info.itabConvs)
1941}
1942
1943// isShapeDeref returns true if t is either a shape or a pointer to a shape. (We
1944// can't just use deref(t).IsShape(), since a shape type is a complex type and may
1945// have a pointer as part of its shape.)
1946func isShapeDeref(t *types.Type) bool {
1947	return t.IsShape() || t.IsPtr() && t.Elem().IsShape()
1948}
1949
1950// addType adds t to info.derivedTypes if it is parameterized type (which is not
1951// just a simple shape) that is different from any existing type on
1952// info.derivedTypes.
1953func addType(info *dictInfo, n ir.Node, t *types.Type) {
1954	if t == nil || !t.HasShape() {
1955		return
1956	}
1957	if t.IsShape() {
1958		return
1959	}
1960	if t.Kind() == types.TFUNC && n != nil &&
1961		(t.Recv() != nil || n.Op() == ir.ONAME && n.Name().Class == ir.PFUNC) {
1962		// Don't use the type of a named generic function or method,
1963		// since that is parameterized by other typeparams.
1964		// (They all come from arguments of a FUNCINST node.)
1965		return
1966	}
1967	if doubleCheck && !parameterizedBy(t, info.shapeParams) {
1968		base.Fatalf("adding type with invalid parameters %+v", t)
1969	}
1970	if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() {
1971		// Multiple return values are not a relevant new type (?).
1972		return
1973	}
1974	// Ignore a derived type we've already added.
1975	for _, et := range info.derivedTypes {
1976		if types.IdenticalStrict(t, et) {
1977			return
1978		}
1979	}
1980	info.derivedTypes = append(info.derivedTypes, t)
1981}
1982
1983// parameterizedBy returns true if t is parameterized by (at most) params.
1984func parameterizedBy(t *types.Type, params []*types.Type) bool {
1985	return parameterizedBy1(t, params, map[*types.Type]bool{})
1986}
1987func parameterizedBy1(t *types.Type, params []*types.Type, visited map[*types.Type]bool) bool {
1988	if visited[t] {
1989		return true
1990	}
1991	visited[t] = true
1992
1993	if t.Sym() != nil && len(t.RParams()) > 0 {
1994		// This defined type is instantiated. Check the instantiating types.
1995		for _, r := range t.RParams() {
1996			if !parameterizedBy1(r, params, visited) {
1997				return false
1998			}
1999		}
2000		return true
2001	}
2002	if t.IsShape() {
2003		// Check if t is one of the allowed parameters in scope.
2004		for _, p := range params {
2005			if p == t {
2006				return true
2007			}
2008		}
2009		// Couldn't find t in the list of allowed parameters.
2010		return false
2011
2012	}
2013	switch t.Kind() {
2014	case types.TARRAY, types.TPTR, types.TSLICE, types.TCHAN:
2015		return parameterizedBy1(t.Elem(), params, visited)
2016
2017	case types.TMAP:
2018		return parameterizedBy1(t.Key(), params, visited) && parameterizedBy1(t.Elem(), params, visited)
2019
2020	case types.TFUNC:
2021		return parameterizedBy1(t.TParams(), params, visited) && parameterizedBy1(t.Recvs(), params, visited) && parameterizedBy1(t.Params(), params, visited) && parameterizedBy1(t.Results(), params, visited)
2022
2023	case types.TSTRUCT:
2024		for _, f := range t.Fields().Slice() {
2025			if !parameterizedBy1(f.Type, params, visited) {
2026				return false
2027			}
2028		}
2029		return true
2030
2031	case types.TINTER:
2032		for _, f := range t.Methods().Slice() {
2033			if !parameterizedBy1(f.Type, params, visited) {
2034				return false
2035			}
2036		}
2037		return true
2038
2039	case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
2040		types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64,
2041		types.TUINTPTR, types.TBOOL, types.TSTRING, types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128, types.TUNSAFEPTR:
2042		return true
2043
2044	case types.TUNION:
2045		for i := 0; i < t.NumTerms(); i++ {
2046			tt, _ := t.Term(i)
2047			if !parameterizedBy1(tt, params, visited) {
2048				return false
2049			}
2050		}
2051		return true
2052
2053	default:
2054		base.Fatalf("bad type kind %+v", t)
2055		return true
2056	}
2057}
2058
2059// startClosures starts creation of a closure that has the function type typ. It
2060// creates all the formal params and results according to the type typ. On return,
2061// the body and closure variables of the closure must still be filled in, and
2062// ir.UseClosure() called.
2063func startClosure(pos src.XPos, outer *ir.Func, typ *types.Type) (*ir.Func, []*types.Field, []*types.Field) {
2064	// Make a new internal function.
2065	fn := ir.NewClosureFunc(pos, outer != nil)
2066	ir.NameClosure(fn.OClosure, outer)
2067
2068	// Build formal argument and return lists.
2069	var formalParams []*types.Field  // arguments of closure
2070	var formalResults []*types.Field // returns of closure
2071	for i := 0; i < typ.NumParams(); i++ {
2072		t := typ.Params().Field(i).Type
2073		arg := ir.NewNameAt(pos, typecheck.LookupNum("a", i))
2074		arg.Class = ir.PPARAM
2075		typed(t, arg)
2076		arg.Curfn = fn
2077		fn.Dcl = append(fn.Dcl, arg)
2078		f := types.NewField(pos, arg.Sym(), t)
2079		f.Nname = arg
2080		f.SetIsDDD(typ.Params().Field(i).IsDDD())
2081		formalParams = append(formalParams, f)
2082	}
2083	for i := 0; i < typ.NumResults(); i++ {
2084		t := typ.Results().Field(i).Type
2085		result := ir.NewNameAt(pos, typecheck.LookupNum("r", i)) // TODO: names not needed?
2086		result.Class = ir.PPARAMOUT
2087		typed(t, result)
2088		result.Curfn = fn
2089		fn.Dcl = append(fn.Dcl, result)
2090		f := types.NewField(pos, result.Sym(), t)
2091		f.Nname = result
2092		formalResults = append(formalResults, f)
2093	}
2094
2095	// Build an internal function with the right signature.
2096	closureType := types.NewSignature(typ.Pkg(), nil, nil, formalParams, formalResults)
2097	typed(closureType, fn.Nname)
2098	typed(typ, fn.OClosure)
2099	fn.SetTypecheck(1)
2100	return fn, formalParams, formalResults
2101
2102}
2103
2104// assertToBound returns a new node that converts a node rcvr with interface type to
2105// the 'dst' interface type.
2106func assertToBound(info *instInfo, dictVar *ir.Name, pos src.XPos, rcvr ir.Node, dst *types.Type) ir.Node {
2107	if dst.HasShape() {
2108		ix := findDictType(info, dst)
2109		assert(ix >= 0)
2110		rt := getDictionaryType(info, dictVar, pos, ix)
2111		rcvr = ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, rcvr, rt)
2112		typed(dst, rcvr)
2113	} else {
2114		rcvr = ir.NewTypeAssertExpr(pos, rcvr, nil)
2115		typed(dst, rcvr)
2116	}
2117	return rcvr
2118}
2119
2120// buildClosure2 makes a closure to implement a method expression m (generic form x)
2121// which has a shape type as receiver. If the receiver is exactly a shape (i.e. from
2122// a typeparam), then the body of the closure converts m.X (the receiver) to the
2123// interface bound type, and makes an interface call with the remaining arguments.
2124//
2125// The returned closure is fully substituted and has already had any needed
2126// transformations done.
2127func (g *genInst) buildClosure2(info *instInfo, m ir.Node) ir.Node {
2128	outer := info.fun
2129	pos := m.Pos()
2130	typ := m.Type() // type of the closure
2131
2132	fn, formalParams, formalResults := startClosure(pos, outer, typ)
2133
2134	// Capture dictionary calculated in the outer function
2135	dictVar := ir.CaptureName(pos, fn, info.dictParam)
2136	typed(types.Types[types.TUINTPTR], dictVar)
2137
2138	// Build arguments to call inside the closure.
2139	var args []ir.Node
2140	for i := 0; i < typ.NumParams(); i++ {
2141		args = append(args, formalParams[i].Nname.(*ir.Name))
2142	}
2143
2144	// Build call itself. This involves converting the first argument to the
2145	// bound type (an interface) using the dictionary, and then making an
2146	// interface call with the remaining arguments.
2147	var innerCall ir.Node
2148	rcvr := args[0]
2149	args = args[1:]
2150	assert(m.(*ir.SelectorExpr).X.Type().IsShape())
2151	dst := info.dictInfo.shapeToBound[m.(*ir.SelectorExpr).X.Type()]
2152	if m.(*ir.SelectorExpr).X.Type().IsInterface() {
2153		// If type arg is an interface (unusual case), we do a type assert to
2154		// the type bound.
2155		rcvr = assertToBound(info, dictVar, pos, rcvr, dst)
2156	} else {
2157		rcvr = convertUsingDictionary(info, dictVar, pos, rcvr, m, dst)
2158	}
2159	dot := ir.NewSelectorExpr(pos, ir.ODOTINTER, rcvr, m.(*ir.SelectorExpr).Sel)
2160	dot.Selection = typecheck.Lookdot1(dot, dot.Sel, dot.X.Type(), dot.X.Type().AllMethods(), 1)
2161
2162	typed(dot.Selection.Type, dot)
2163	innerCall = ir.NewCallExpr(pos, ir.OCALLINTER, dot, args)
2164	t := m.Type()
2165	if t.NumResults() == 0 {
2166		innerCall.SetTypecheck(1)
2167	} else if t.NumResults() == 1 {
2168		typed(t.Results().Field(0).Type, innerCall)
2169	} else {
2170		typed(t.Results(), innerCall)
2171	}
2172	if len(formalResults) > 0 {
2173		innerCall = ir.NewReturnStmt(pos, []ir.Node{innerCall})
2174		innerCall.SetTypecheck(1)
2175	}
2176	fn.Body = []ir.Node{innerCall}
2177
2178	// We're all done with the captured dictionary
2179	ir.FinishCaptureNames(pos, outer, fn)
2180
2181	// Do final checks on closure and return it.
2182	return ir.UseClosure(fn.OClosure, typecheck.Target)
2183}
2184