// f(p)
// }
//
- // We can turn the first example into the second example by renaming type
- // parameters in the original signature to give them a new identity. As an
- // optimization, we do this only for self-recursive calls.
-
- // We can detect if we are in a self-recursive call by comparing the
- // identity of the first type parameter in the current function with the
- // first type parameter in tparams. This works because type parameters are
- // unique to their type parameter list.
- selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
- if selfRecursive {
- // In self-recursive inference, rename the type parameters with new type
- // parameters that are the same but for their pointer identity.
- tparams2 := make([]*TypeParam, len(tparams))
- for i, tparam := range tparams {
- tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
- tparams2[i] = NewTypeParam(tname, nil)
- tparams2[i].index = tparam.index // == i
- }
-
- renameMap := makeRenameMap(tparams, tparams2)
- for i, tparam := range tparams {
- tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
- }
+ // We turn the first example into the second example by renaming type
+ // parameters in the original signature to give them a new identity.
+ tparams2 := make([]*TypeParam, len(tparams))
+ for i, tparam := range tparams {
+ tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+ tparams2[i] = NewTypeParam(tname, nil)
+ tparams2[i].index = tparam.index // == i
+ }
- tparams = tparams2
- params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
+ renameMap := makeRenameMap(tparams, tparams2)
+ for i, tparam := range tparams {
+ tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
}
+
+ tparams = tparams2
+ params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
}
// If we have more than 2 arguments, we may have arguments with named and unnamed types.
// f(p)
// }
//
- // We can turn the first example into the second example by renaming type
- // parameters in the original signature to give them a new identity. As an
- // optimization, we do this only for self-recursive calls.
-
- // We can detect if we are in a self-recursive call by comparing the
- // identity of the first type parameter in the current function with the
- // first type parameter in tparams. This works because type parameters are
- // unique to their type parameter list.
- selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
- if selfRecursive {
- // In self-recursive inference, rename the type parameters with new type
- // parameters that are the same but for their pointer identity.
- tparams2 := make([]*TypeParam, len(tparams))
- for i, tparam := range tparams {
- tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
- tparams2[i] = NewTypeParam(tname, nil)
- tparams2[i].index = tparam.index // == i
- }
-
- renameMap := makeRenameMap(tparams, tparams2)
- for i, tparam := range tparams {
- tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
- }
+ // We turn the first example into the second example by renaming type
+ // parameters in the original signature to give them a new identity.
+ tparams2 := make([]*TypeParam, len(tparams))
+ for i, tparam := range tparams {
+ tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+ tparams2[i] = NewTypeParam(tname, nil)
+ tparams2[i].index = tparam.index // == i
+ }
- tparams = tparams2
- params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
+ renameMap := makeRenameMap(tparams, tparams2)
+ for i, tparam := range tparams {
+ tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
}
+
+ tparams = tparams2
+ params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
}
// If we have more than 2 arguments, we may have arguments with named and unnamed types.
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[P *Q, Q any](p P, q Q) {
+ func() {
+ _ = f[P]
+ f(p, q)
+ f[P](p, q)
+ f[P, Q](p, q)
+ }()
+}