}
// Rename type parameters to avoid problems with recursive instantiations.
- // Note that NewTuple(params...) below is nil if len(params) == 0, as desired.
+ // Note that NewTuple(params...) below is (*Tuple)(nil) if len(params) == 0, as desired.
tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))
- targs = check.infer(pos, tparams, targs, params2, args)
+ targs = check.infer(pos, tparams, targs, params2.(*Tuple), args)
if targs == nil {
// error was already reported
x.mode = invalid
}
}
// rename type parameters to avoid problems with recursive calls
- tparams, sigParams = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
+ var tmp Type
+ tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
+ sigParams = tmp.(*Tuple)
}
// collect type parameters from generic function arguments
return
}
-// renameTParams renames the type parameters in a function signature described by its
-// type and ordinary parameters (tparams and params) such that each type parameter is
-// given a new identity. renameTParams returns the new type and ordinary parameters.
+// renameTParams renames the type parameters in the given type such that each type
+// parameter is given a new identity. renameTParams returns the new type parameters
+// and updated type. If the result type is unchanged from the argument type, none
+// of the type parameters in tparams occurred in the type.
+// If typ is a generic function, type parameters held with typ are not changed and
+// must be updated separately if desired.
// The positions is only used for debug traces.
-func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
+func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, typ Type) ([]*TypeParam, Type) {
// For the purpose of type inference we must differentiate type parameters
// occurring in explicit type or value function arguments from the type
// parameters we are solving for via unification because they may be the
// Type parameter renaming turns the first example into the second
// example by renaming the type parameter P into P2.
if len(tparams) == 0 {
- return nil, params // nothing to do
+ return nil, typ // nothing to do
}
tparams2 := make([]*TypeParam, len(tparams))
tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
}
- return tparams2, check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
+ return tparams2, check.subst(pos, typ, renameMap, nil, check.context())
}
// typeParamsString produces a string containing all the type parameter names
}
// Rename type parameters to avoid problems with recursive instantiations.
- // Note that NewTuple(params...) below is nil if len(params) == 0, as desired.
+ // Note that NewTuple(params...) below is (*Tuple)(nil) if len(params) == 0, as desired.
tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))
- targs = check.infer(atPos(pos), tparams, targs, params2, args)
+ targs = check.infer(atPos(pos), tparams, targs, params2.(*Tuple), args)
if targs == nil {
// error was already reported
x.mode = invalid
}
}
// rename type parameters to avoid problems with recursive calls
- tparams, sigParams = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
+ var tmp Type
+ tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
+ sigParams = tmp.(*Tuple)
}
// collect type parameters from generic function arguments
return
}
-// renameTParams renames the type parameters in a function signature described by its
-// type and ordinary parameters (tparams and params) such that each type parameter is
-// given a new identity. renameTParams returns the new type and ordinary parameters.
+// renameTParams renames the type parameters in the given type such that each type
+// parameter is given a new identity. renameTParams returns the new type parameters
+// and updated type. If the result type is unchanged from the argument type, none
+// of the type parameters in tparams occurred in the type.
+// If typ is a generic function, type parameters held with typ are not changed and
+// must be updated separately if desired.
// The positions is only used for debug traces.
-func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
+func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, typ Type) ([]*TypeParam, Type) {
// For the purpose of type inference we must differentiate type parameters
// occurring in explicit type or value function arguments from the type
// parameters we are solving for via unification because they may be the
// Type parameter renaming turns the first example into the second
// example by renaming the type parameter P into P2.
if len(tparams) == 0 {
- return nil, params // nothing to do
+ return nil, typ // nothing to do
}
tparams2 := make([]*TypeParam, len(tparams))
tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
}
- return tparams2, check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
+ return tparams2, check.subst(pos, typ, renameMap, nil, check.context())
}
// typeParamsString produces a string containing all the type parameter names