Source file src/go/types/infer.go

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

View as plain text