github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/noder/stencil.go (about)

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