github.com/bir3/gocompiler@v0.3.205/src/go/types/infer.go (about)

     1  // Copyright 2018 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 implements type parameter inference given
     6  // a list of concrete arguments and a parameter list.
     7  
     8  package types
     9  
    10  import (
    11  	"fmt"
    12  	"github.com/bir3/gocompiler/src/go/token"
    13  	. "github.com/bir3/gocompiler/src/internal/types/errors"
    14  	"strings"
    15  )
    16  
    17  // infer attempts to infer the complete set of type arguments for generic function instantiation/call
    18  // based on the given type parameters tparams, type arguments targs, function parameters params, and
    19  // function arguments args, if any. There must be at least one type parameter, no more type arguments
    20  // than type parameters, and params and args must match in number (incl. zero).
    21  // If successful, infer returns the complete list of type arguments, one for each type parameter.
    22  // Otherwise the result is nil and appropriate errors will be reported.
    23  //
    24  // Inference proceeds as follows:
    25  //
    26  //	Starting with given type arguments
    27  //	1) apply FTI (function type inference) with typed arguments,
    28  //	2) apply CTI (constraint type inference),
    29  //	3) apply FTI with untyped function arguments,
    30  //	4) apply CTI.
    31  //
    32  // The process stops as soon as all type arguments are known or an error occurs.
    33  func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type, params *Tuple, args []*operand) (result []Type) {
    34  	if debug {
    35  		defer func() {
    36  			assert(result == nil || len(result) == len(tparams))
    37  			for _, targ := range result {
    38  				assert(targ != nil)
    39  			}
    40  			//check.dump("### inferred targs = %s", result)
    41  		}()
    42  	}
    43  
    44  	if traceInference {
    45  		check.dump("-- inferA %s%s ➞ %s", tparams, params, targs)
    46  		defer func() {
    47  			check.dump("=> inferA %s ➞ %s", tparams, result)
    48  		}()
    49  	}
    50  
    51  	// There must be at least one type parameter, and no more type arguments than type parameters.
    52  	n := len(tparams)
    53  	assert(n > 0 && len(targs) <= n)
    54  
    55  	// Function parameters and arguments must match in number.
    56  	assert(params.Len() == len(args))
    57  
    58  	// If we already have all type arguments, we're done.
    59  	if len(targs) == n {
    60  		return targs
    61  	}
    62  	// len(targs) < n
    63  
    64  	const enableTparamRenaming = true
    65  	if enableTparamRenaming {
    66  		// For the purpose of type inference we must differentiate type parameters
    67  		// occurring in explicit type or value function arguments from the type
    68  		// parameters we are solving for via unification, because they may be the
    69  		// same in self-recursive calls. For example:
    70  		//
    71  		//  func f[P *Q, Q any](p P, q Q) {
    72  		//    f(p)
    73  		//  }
    74  		//
    75  		// In this example, the fact that the P used in the instantation f[P] has
    76  		// the same pointer identity as the P we are trying to solve for via
    77  		// unification is coincidental: there is nothing special about recursive
    78  		// calls that should cause them to conflate the identity of type arguments
    79  		// with type parameters. To put it another way: any such self-recursive
    80  		// call is equivalent to a mutually recursive call, which does not run into
    81  		// any problems of type parameter identity. For example, the following code
    82  		// is equivalent to the code above.
    83  		//
    84  		//  func f[P interface{*Q}, Q any](p P, q Q) {
    85  		//    f2(p)
    86  		//  }
    87  		//
    88  		//  func f2[P interface{*Q}, Q any](p P, q Q) {
    89  		//    f(p)
    90  		//  }
    91  		//
    92  		// We turn the first example into the second example by renaming type
    93  		// parameters in the original signature to give them a new identity.
    94  		tparams2 := make([]*TypeParam, len(tparams))
    95  		for i, tparam := range tparams {
    96  			tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
    97  			tparams2[i] = NewTypeParam(tname, nil)
    98  			tparams2[i].index = tparam.index // == i
    99  		}
   100  
   101  		renameMap := makeRenameMap(tparams, tparams2)
   102  		for i, tparam := range tparams {
   103  			tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
   104  		}
   105  
   106  		tparams = tparams2
   107  		params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
   108  	}
   109  
   110  	// If we have more than 2 arguments, we may have arguments with named and unnamed types.
   111  	// If that is the case, permutate params and args such that the arguments with named
   112  	// types are first in the list. This doesn't affect type inference if all types are taken
   113  	// as is. But when we have inexact unification enabled (as is the case for function type
   114  	// inference), when a named type is unified with an unnamed type, unification proceeds
   115  	// with the underlying type of the named type because otherwise unification would fail
   116  	// right away. This leads to an asymmetry in type inference: in cases where arguments of
   117  	// named and unnamed types are passed to parameters with identical type, different types
   118  	// (named vs underlying) may be inferred depending on the order of the arguments.
   119  	// By ensuring that named types are seen first, order dependence is avoided and unification
   120  	// succeeds where it can (issue #43056).
   121  	const enableArgSorting = true
   122  	if m := len(args); m >= 2 && enableArgSorting {
   123  		// Determine indices of arguments with named and unnamed types.
   124  		var named, unnamed []int
   125  		for i, arg := range args {
   126  			if hasName(arg.typ) {
   127  				named = append(named, i)
   128  			} else {
   129  				unnamed = append(unnamed, i)
   130  			}
   131  		}
   132  
   133  		// If we have named and unnamed types, move the arguments with
   134  		// named types first. Update the parameter list accordingly.
   135  		// Make copies so as not to clobber the incoming slices.
   136  		if len(named) != 0 && len(unnamed) != 0 {
   137  			params2 := make([]*Var, m)
   138  			args2 := make([]*operand, m)
   139  			i := 0
   140  			for _, j := range named {
   141  				params2[i] = params.At(j)
   142  				args2[i] = args[j]
   143  				i++
   144  			}
   145  			for _, j := range unnamed {
   146  				params2[i] = params.At(j)
   147  				args2[i] = args[j]
   148  				i++
   149  			}
   150  			params = NewTuple(params2...)
   151  			args = args2
   152  		}
   153  	}
   154  
   155  	// --- 1 ---
   156  	// Continue with the type arguments we have. Avoid matching generic
   157  	// parameters that already have type arguments against function arguments:
   158  	// It may fail because matching uses type identity while parameter passing
   159  	// uses assignment rules. Instantiate the parameter list with the type
   160  	// arguments we have, and continue with that parameter list.
   161  
   162  	// First, make sure we have a "full" list of type arguments, some of which
   163  	// may be nil (unknown). Make a copy so as to not clobber the incoming slice.
   164  	if len(targs) < n {
   165  		targs2 := make([]Type, n)
   166  		copy(targs2, targs)
   167  		targs = targs2
   168  	}
   169  	// len(targs) == n
   170  
   171  	// Substitute type arguments for their respective type parameters in params,
   172  	// if any. Note that nil targs entries are ignored by check.subst.
   173  	// TODO(gri) Can we avoid this (we're setting known type arguments below,
   174  	//           but that doesn't impact the isParameterized check for now).
   175  	if params.Len() > 0 {
   176  		smap := makeSubstMap(tparams, targs)
   177  		params = check.subst(token.NoPos, params, smap, nil, check.context()).(*Tuple)
   178  	}
   179  
   180  	// Unify parameter and argument types for generic parameters with typed arguments
   181  	// and collect the indices of generic parameters with untyped arguments.
   182  	// Terminology: generic parameter = function parameter with a type-parameterized type
   183  	u := newUnifier(false)
   184  	u.x.init(tparams)
   185  
   186  	// Set the type arguments which we know already.
   187  	for i, targ := range targs {
   188  		if targ != nil {
   189  			u.x.set(i, targ)
   190  		}
   191  	}
   192  
   193  	errorf := func(kind string, tpar, targ Type, arg *operand) {
   194  		// provide a better error message if we can
   195  		targs, index := u.x.types()
   196  		if index == 0 {
   197  			// The first type parameter couldn't be inferred.
   198  			// If none of them could be inferred, don't try
   199  			// to provide the inferred type in the error msg.
   200  			allFailed := true
   201  			for _, targ := range targs {
   202  				if targ != nil {
   203  					allFailed = false
   204  					break
   205  				}
   206  			}
   207  			if allFailed {
   208  				check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
   209  				return
   210  			}
   211  		}
   212  		smap := makeSubstMap(tparams, targs)
   213  		// TODO(rFindley): pass a positioner here, rather than arg.Pos().
   214  		inferred := check.subst(arg.Pos(), tpar, smap, nil, check.context())
   215  		// _CannotInferTypeArgs indicates a failure of inference, though the actual
   216  		// error may be better attributed to a user-provided type argument (hence
   217  		// _InvalidTypeArg). We can't differentiate these cases, so fall back on
   218  		// the more general _CannotInferTypeArgs.
   219  		if inferred != tpar {
   220  			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
   221  		} else {
   222  			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
   223  		}
   224  	}
   225  
   226  	// indices of the generic parameters with untyped arguments - save for later
   227  	var indices []int
   228  	for i, arg := range args {
   229  		par := params.At(i)
   230  		// If we permit bidirectional unification, this conditional code needs to be
   231  		// executed even if par.typ is not parameterized since the argument may be a
   232  		// generic function (for which we want to infer its type arguments).
   233  		if isParameterized(tparams, par.typ) {
   234  			if arg.mode == invalid {
   235  				// An error was reported earlier. Ignore this targ
   236  				// and continue, we may still be able to infer all
   237  				// targs resulting in fewer follow-on errors.
   238  				continue
   239  			}
   240  			if targ := arg.typ; isTyped(targ) {
   241  				// If we permit bidirectional unification, and targ is
   242  				// a generic function, we need to initialize u.y with
   243  				// the respective type parameters of targ.
   244  				if !u.unify(par.typ, targ) {
   245  					errorf("type", par.typ, targ, arg)
   246  					return nil
   247  				}
   248  			} else if _, ok := par.typ.(*TypeParam); ok {
   249  				// Since default types are all basic (i.e., non-composite) types, an
   250  				// untyped argument will never match a composite parameter type; the
   251  				// only parameter type it can possibly match against is a *TypeParam.
   252  				// Thus, for untyped arguments we only need to look at parameter types
   253  				// that are single type parameters.
   254  				indices = append(indices, i)
   255  			}
   256  		}
   257  	}
   258  
   259  	// If we've got all type arguments, we're done.
   260  	var index int
   261  	targs, index = u.x.types()
   262  	if index < 0 {
   263  		return targs
   264  	}
   265  
   266  	// --- 2 ---
   267  	// See how far we get with constraint type inference.
   268  	// Note that even if we don't have any type arguments, constraint type inference
   269  	// may produce results for constraints that explicitly specify a type.
   270  	targs, index = check.inferB(posn, tparams, targs)
   271  	if targs == nil || index < 0 {
   272  		return targs
   273  	}
   274  
   275  	// --- 3 ---
   276  	// Use any untyped arguments to infer additional type arguments.
   277  	// Some generic parameters with untyped arguments may have been given
   278  	// a type by now, we can ignore them.
   279  	for _, i := range indices {
   280  		tpar := params.At(i).typ.(*TypeParam) // is type parameter by construction of indices
   281  		// Only consider untyped arguments for which the corresponding type
   282  		// parameter doesn't have an inferred type yet.
   283  		if targs[tpar.index] == nil {
   284  			arg := args[i]
   285  			targ := Default(arg.typ)
   286  			// The default type for an untyped nil is untyped nil. We must not
   287  			// infer an untyped nil type as type parameter type. Ignore untyped
   288  			// nil by making sure all default argument types are typed.
   289  			if isTyped(targ) && !u.unify(tpar, targ) {
   290  				errorf("default type", tpar, targ, arg)
   291  				return nil
   292  			}
   293  		}
   294  	}
   295  
   296  	// If we've got all type arguments, we're done.
   297  	targs, index = u.x.types()
   298  	if index < 0 {
   299  		return targs
   300  	}
   301  
   302  	// --- 4 ---
   303  	// Again, follow up with constraint type inference.
   304  	targs, index = check.inferB(posn, tparams, targs)
   305  	if targs == nil || index < 0 {
   306  		return targs
   307  	}
   308  
   309  	// At least one type argument couldn't be inferred.
   310  	assert(index >= 0 && targs[index] == nil)
   311  	tpar := tparams[index]
   312  	check.errorf(posn, CannotInferTypeArgs, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
   313  	return nil
   314  }
   315  
   316  // typeParamsString produces a string containing all the type parameter names
   317  // in list suitable for human consumption.
   318  func typeParamsString(list []*TypeParam) string {
   319  	// common cases
   320  	n := len(list)
   321  	switch n {
   322  	case 0:
   323  		return ""
   324  	case 1:
   325  		return list[0].obj.name
   326  	case 2:
   327  		return list[0].obj.name + " and " + list[1].obj.name
   328  	}
   329  
   330  	// general case (n > 2)
   331  	var buf strings.Builder
   332  	for i, tname := range list[:n-1] {
   333  		if i > 0 {
   334  			buf.WriteString(", ")
   335  		}
   336  		buf.WriteString(tname.obj.name)
   337  	}
   338  	buf.WriteString(", and ")
   339  	buf.WriteString(list[n-1].obj.name)
   340  	return buf.String()
   341  }
   342  
   343  // isParameterized reports whether typ contains any of the type parameters of tparams.
   344  func isParameterized(tparams []*TypeParam, typ Type) bool {
   345  	w := tpWalker{
   346  		seen:    make(map[Type]bool),
   347  		tparams: tparams,
   348  	}
   349  	return w.isParameterized(typ)
   350  }
   351  
   352  type tpWalker struct {
   353  	seen    map[Type]bool
   354  	tparams []*TypeParam
   355  }
   356  
   357  func (w *tpWalker) isParameterized(typ Type) (res bool) {
   358  	// detect cycles
   359  	if x, ok := w.seen[typ]; ok {
   360  		return x
   361  	}
   362  	w.seen[typ] = false
   363  	defer func() {
   364  		w.seen[typ] = res
   365  	}()
   366  
   367  	switch t := typ.(type) {
   368  	case nil, *Basic: // TODO(gri) should nil be handled here?
   369  		break
   370  
   371  	case *Array:
   372  		return w.isParameterized(t.elem)
   373  
   374  	case *Slice:
   375  		return w.isParameterized(t.elem)
   376  
   377  	case *Struct:
   378  		for _, fld := range t.fields {
   379  			if w.isParameterized(fld.typ) {
   380  				return true
   381  			}
   382  		}
   383  
   384  	case *Pointer:
   385  		return w.isParameterized(t.base)
   386  
   387  	case *Tuple:
   388  		n := t.Len()
   389  		for i := 0; i < n; i++ {
   390  			if w.isParameterized(t.At(i).typ) {
   391  				return true
   392  			}
   393  		}
   394  
   395  	case *Signature:
   396  		// t.tparams may not be nil if we are looking at a signature
   397  		// of a generic function type (or an interface method) that is
   398  		// part of the type we're testing. We don't care about these type
   399  		// parameters.
   400  		// Similarly, the receiver of a method may declare (rather then
   401  		// use) type parameters, we don't care about those either.
   402  		// Thus, we only need to look at the input and result parameters.
   403  		return w.isParameterized(t.params) || w.isParameterized(t.results)
   404  
   405  	case *Interface:
   406  		tset := t.typeSet()
   407  		for _, m := range tset.methods {
   408  			if w.isParameterized(m.typ) {
   409  				return true
   410  			}
   411  		}
   412  		return tset.is(func(t *term) bool {
   413  			return t != nil && w.isParameterized(t.typ)
   414  		})
   415  
   416  	case *Map:
   417  		return w.isParameterized(t.key) || w.isParameterized(t.elem)
   418  
   419  	case *Chan:
   420  		return w.isParameterized(t.elem)
   421  
   422  	case *Named:
   423  		return w.isParameterizedTypeList(t.TypeArgs().list())
   424  
   425  	case *TypeParam:
   426  		// t must be one of w.tparams
   427  		return tparamIndex(w.tparams, t) >= 0
   428  
   429  	default:
   430  		unreachable()
   431  	}
   432  
   433  	return false
   434  }
   435  
   436  func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
   437  	for _, t := range list {
   438  		if w.isParameterized(t) {
   439  			return true
   440  		}
   441  	}
   442  	return false
   443  }
   444  
   445  // inferB returns the list of actual type arguments inferred from the type parameters'
   446  // bounds and an initial set of type arguments. If type inference is impossible because
   447  // unification fails, an error is reported if report is set to true, the resulting types
   448  // list is nil, and index is 0.
   449  // Otherwise, types is the list of inferred type arguments, and index is the index of the
   450  // first type argument in that list that couldn't be inferred (and thus is nil). If all
   451  // type arguments were inferred successfully, index is < 0. The number of type arguments
   452  // provided may be less than the number of type parameters, but there must be at least one.
   453  func (check *Checker) inferB(posn positioner, tparams []*TypeParam, targs []Type) (types []Type, index int) {
   454  	assert(len(tparams) >= len(targs) && len(targs) > 0)
   455  
   456  	if traceInference {
   457  		check.dump("-- inferB %s ➞ %s", tparams, targs)
   458  		defer func() {
   459  			check.dump("=> inferB %s ➞ %s", tparams, types)
   460  		}()
   461  	}
   462  
   463  	// Setup bidirectional unification between constraints
   464  	// and the corresponding type arguments (which may be nil!).
   465  	u := newUnifier(false)
   466  	u.x.init(tparams)
   467  	u.y = u.x // type parameters between LHS and RHS of unification are identical
   468  
   469  	// Set the type arguments which we know already.
   470  	for i, targ := range targs {
   471  		if targ != nil {
   472  			u.x.set(i, targ)
   473  		}
   474  	}
   475  
   476  	// Repeatedly apply constraint type inference as long as
   477  	// there are still unknown type arguments and progress is
   478  	// being made.
   479  	//
   480  	// This is an O(n^2) algorithm where n is the number of
   481  	// type parameters: if there is progress (and iteration
   482  	// continues), at least one type argument is inferred
   483  	// per iteration and we have a doubly nested loop.
   484  	// In practice this is not a problem because the number
   485  	// of type parameters tends to be very small (< 5 or so).
   486  	// (It should be possible for unification to efficiently
   487  	// signal newly inferred type arguments; then the loops
   488  	// here could handle the respective type parameters only,
   489  	// but that will come at a cost of extra complexity which
   490  	// may not be worth it.)
   491  	for n := u.x.unknowns(); n > 0; {
   492  		nn := n
   493  
   494  		for i, tpar := range tparams {
   495  			// If there is a core term (i.e., a core type with tilde information)
   496  			// unify the type parameter with the core type.
   497  			if core, single := coreTerm(tpar); core != nil {
   498  				// A type parameter can be unified with its core type in two cases.
   499  				tx := u.x.at(i)
   500  				switch {
   501  				case tx != nil:
   502  					// The corresponding type argument tx is known.
   503  					// In this case, if the core type has a tilde, the type argument's underlying
   504  					// type must match the core type, otherwise the type argument and the core type
   505  					// must match.
   506  					// If tx is an external type parameter, don't consider its underlying type
   507  					// (which is an interface). Core type unification will attempt to unify against
   508  					// core.typ.
   509  					// Note also that even with inexact unification we cannot leave away the under
   510  					// call here because it's possible that both tx and core.typ are named types,
   511  					// with under(tx) being a (named) basic type matching core.typ. Such cases do
   512  					// not match with inexact unification.
   513  					if core.tilde && !isTypeParam(tx) {
   514  						tx = under(tx)
   515  					}
   516  					if !u.unify(tx, core.typ) {
   517  						// TODO(gri) improve error message by providing the type arguments
   518  						//           which we know already
   519  						// Don't use term.String() as it always qualifies types, even if they
   520  						// are in the current package.
   521  						tilde := ""
   522  						if core.tilde {
   523  							tilde = "~"
   524  						}
   525  						check.errorf(posn, InvalidTypeArg, "%s does not match %s%s", tx, tilde, core.typ)
   526  						return nil, 0
   527  					}
   528  
   529  				case single && !core.tilde:
   530  					// The corresponding type argument tx is unknown and there's a single
   531  					// specific type and no tilde.
   532  					// In this case the type argument must be that single type; set it.
   533  					u.x.set(i, core.typ)
   534  
   535  				default:
   536  					// Unification is not possible and no progress was made.
   537  					continue
   538  				}
   539  
   540  				// The number of known type arguments may have changed.
   541  				nn = u.x.unknowns()
   542  				if nn == 0 {
   543  					break // all type arguments are known
   544  				}
   545  			}
   546  		}
   547  
   548  		assert(nn <= n)
   549  		if nn == n {
   550  			break // no progress
   551  		}
   552  		n = nn
   553  	}
   554  
   555  	// u.x.types() now contains the incoming type arguments plus any additional type
   556  	// arguments which were inferred from core terms. The newly inferred non-nil
   557  	// entries may still contain references to other type parameters.
   558  	// For instance, for [A any, B interface{ []C }, C interface{ *A }], if A == int
   559  	// was given, unification produced the type list [int, []C, *A]. We eliminate the
   560  	// remaining type parameters by substituting the type parameters in this type list
   561  	// until nothing changes anymore.
   562  	types, _ = u.x.types()
   563  	if debug {
   564  		for i, targ := range targs {
   565  			assert(targ == nil || types[i] == targ)
   566  		}
   567  	}
   568  
   569  	// The data structure of each (provided or inferred) type represents a graph, where
   570  	// each node corresponds to a type and each (directed) vertex points to a component
   571  	// type. The substitution process described above repeatedly replaces type parameter
   572  	// nodes in these graphs with the graphs of the types the type parameters stand for,
   573  	// which creates a new (possibly bigger) graph for each type.
   574  	// The substitution process will not stop if the replacement graph for a type parameter
   575  	// also contains that type parameter.
   576  	// For instance, for [A interface{ *A }], without any type argument provided for A,
   577  	// unification produces the type list [*A]. Substituting A in *A with the value for
   578  	// A will lead to infinite expansion by producing [**A], [****A], [********A], etc.,
   579  	// because the graph A -> *A has a cycle through A.
   580  	// Generally, cycles may occur across multiple type parameters and inferred types
   581  	// (for instance, consider [P interface{ *Q }, Q interface{ func(P) }]).
   582  	// We eliminate cycles by walking the graphs for all type parameters. If a cycle
   583  	// through a type parameter is detected, cycleFinder nils out the respective type
   584  	// which kills the cycle; this also means that the respective type could not be
   585  	// inferred.
   586  	//
   587  	// TODO(gri) If useful, we could report the respective cycle as an error. We don't
   588  	//           do this now because type inference will fail anyway, and furthermore,
   589  	//           constraints with cycles of this kind cannot currently be satisfied by
   590  	//           any user-supplied type. But should that change, reporting an error
   591  	//           would be wrong.
   592  	w := cycleFinder{tparams, types, make(map[Type]bool)}
   593  	for _, t := range tparams {
   594  		w.typ(t) // t != nil
   595  	}
   596  
   597  	// dirty tracks the indices of all types that may still contain type parameters.
   598  	// We know that nil type entries and entries corresponding to provided (non-nil)
   599  	// type arguments are clean, so exclude them from the start.
   600  	var dirty []int
   601  	for i, typ := range types {
   602  		if typ != nil && (i >= len(targs) || targs[i] == nil) {
   603  			dirty = append(dirty, i)
   604  		}
   605  	}
   606  
   607  	for len(dirty) > 0 {
   608  		// TODO(gri) Instead of creating a new substMap for each iteration,
   609  		// provide an update operation for substMaps and only change when
   610  		// needed. Optimization.
   611  		smap := makeSubstMap(tparams, types)
   612  		n := 0
   613  		for _, index := range dirty {
   614  			t0 := types[index]
   615  			if t1 := check.subst(token.NoPos, t0, smap, nil, check.context()); t1 != t0 {
   616  				types[index] = t1
   617  				dirty[n] = index
   618  				n++
   619  			}
   620  		}
   621  		dirty = dirty[:n]
   622  	}
   623  
   624  	// Once nothing changes anymore, we may still have type parameters left;
   625  	// e.g., a constraint with core type *P may match a type parameter Q but
   626  	// we don't have any type arguments to fill in for *P or Q (issue #45548).
   627  	// Don't let such inferences escape, instead nil them out.
   628  	for i, typ := range types {
   629  		if typ != nil && isParameterized(tparams, typ) {
   630  			types[i] = nil
   631  		}
   632  	}
   633  
   634  	// update index
   635  	index = -1
   636  	for i, typ := range types {
   637  		if typ == nil {
   638  			index = i
   639  			break
   640  		}
   641  	}
   642  
   643  	return
   644  }
   645  
   646  // If the type parameter has a single specific type S, coreTerm returns (S, true).
   647  // Otherwise, if tpar has a core type T, it returns a term corresponding to that
   648  // core type and false. In that case, if any term of tpar has a tilde, the core
   649  // term has a tilde. In all other cases coreTerm returns (nil, false).
   650  func coreTerm(tpar *TypeParam) (*term, bool) {
   651  	n := 0
   652  	var single *term // valid if n == 1
   653  	var tilde bool
   654  	tpar.is(func(t *term) bool {
   655  		if t == nil {
   656  			assert(n == 0)
   657  			return false // no terms
   658  		}
   659  		n++
   660  		single = t
   661  		if t.tilde {
   662  			tilde = true
   663  		}
   664  		return true
   665  	})
   666  	if n == 1 {
   667  		if debug {
   668  			assert(debug && under(single.typ) == coreType(tpar))
   669  		}
   670  		return single, true
   671  	}
   672  	if typ := coreType(tpar); typ != nil {
   673  		// A core type is always an underlying type.
   674  		// If any term of tpar has a tilde, we don't
   675  		// have a precise core type and we must return
   676  		// a tilde as well.
   677  		return &term{tilde, typ}, false
   678  	}
   679  	return nil, false
   680  }
   681  
   682  type cycleFinder struct {
   683  	tparams []*TypeParam
   684  	types   []Type
   685  	seen    map[Type]bool
   686  }
   687  
   688  func (w *cycleFinder) typ(typ Type) {
   689  	if w.seen[typ] {
   690  		// We have seen typ before. If it is one of the type parameters
   691  		// in tparams, iterative substitution will lead to infinite expansion.
   692  		// Nil out the corresponding type which effectively kills the cycle.
   693  		if tpar, _ := typ.(*TypeParam); tpar != nil {
   694  			if i := tparamIndex(w.tparams, tpar); i >= 0 {
   695  				// cycle through tpar
   696  				w.types[i] = nil
   697  			}
   698  		}
   699  		// If we don't have one of our type parameters, the cycle is due
   700  		// to an ordinary recursive type and we can just stop walking it.
   701  		return
   702  	}
   703  	w.seen[typ] = true
   704  	defer delete(w.seen, typ)
   705  
   706  	switch t := typ.(type) {
   707  	case *Basic:
   708  		// nothing to do
   709  
   710  	case *Array:
   711  		w.typ(t.elem)
   712  
   713  	case *Slice:
   714  		w.typ(t.elem)
   715  
   716  	case *Struct:
   717  		w.varList(t.fields)
   718  
   719  	case *Pointer:
   720  		w.typ(t.base)
   721  
   722  	// case *Tuple:
   723  	//      This case should not occur because tuples only appear
   724  	//      in signatures where they are handled explicitly.
   725  
   726  	case *Signature:
   727  		if t.params != nil {
   728  			w.varList(t.params.vars)
   729  		}
   730  		if t.results != nil {
   731  			w.varList(t.results.vars)
   732  		}
   733  
   734  	case *Union:
   735  		for _, t := range t.terms {
   736  			w.typ(t.typ)
   737  		}
   738  
   739  	case *Interface:
   740  		for _, m := range t.methods {
   741  			w.typ(m.typ)
   742  		}
   743  		for _, t := range t.embeddeds {
   744  			w.typ(t)
   745  		}
   746  
   747  	case *Map:
   748  		w.typ(t.key)
   749  		w.typ(t.elem)
   750  
   751  	case *Chan:
   752  		w.typ(t.elem)
   753  
   754  	case *Named:
   755  		for _, tpar := range t.TypeArgs().list() {
   756  			w.typ(tpar)
   757  		}
   758  
   759  	case *TypeParam:
   760  		if i := tparamIndex(w.tparams, t); i >= 0 && w.types[i] != nil {
   761  			w.typ(w.types[i])
   762  		}
   763  
   764  	default:
   765  		panic(fmt.Sprintf("unexpected %T", typ))
   766  	}
   767  }
   768  
   769  func (w *cycleFinder) varList(list []*Var) {
   770  	for _, v := range list {
   771  		w.typ(v.typ)
   772  	}
   773  }