mirror of
https://github.com/golang/go
synced 2024-11-16 16:14:40 -07:00
go/types, types2: fix comment in Checker.renameTParams
The original comment examples didn't pass the correct number of function arguments. Rather than fixing that, use a simpler example and adjust prose a bit. Change-Id: I2806737a2b8f9c4b876911b214f3d9e28213fc27 Reviewed-on: https://go-review.googlesource.com/c/go/+/470918 Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
ffb07d0c66
commit
53a5d2541c
@ -219,32 +219,31 @@ func (check *Checker) infer1(pos syntax.Pos, tparams []*TypeParam, targs []Type,
|
|||||||
func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
|
func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
|
||||||
// For the purpose of type inference we must differentiate type parameters
|
// For the purpose of type inference we must differentiate type parameters
|
||||||
// occurring in explicit type or value function arguments from the type
|
// occurring in explicit type or value function arguments from the type
|
||||||
// parameters we are solving for via unification, because they may be the
|
// parameters we are solving for via unification because they may be the
|
||||||
// same in self-recursive calls. For example:
|
// same in self-recursive calls:
|
||||||
//
|
//
|
||||||
// func f[P *Q, Q any](p P, q Q) {
|
// func f[P constraint](x P) {
|
||||||
// f(p)
|
// f(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// In this example, the fact that the P used in the instantation f[P] has
|
// In this example, without type parameter renaming, the P used in the
|
||||||
// the same pointer identity as the P we are trying to solve for via
|
// instantation f[P] has the same pointer identity as the P we are trying
|
||||||
// unification is coincidental: there is nothing special about recursive
|
// to solve for through type inference. This causes problems for type
|
||||||
// calls that should cause them to conflate the identity of type arguments
|
// unification. Because any such self-recursive call is equivalent to
|
||||||
// with type parameters. To put it another way: any such self-recursive
|
// a mutually recursive call, type parameter renaming can be used to
|
||||||
// call is equivalent to a mutually recursive call, which does not run into
|
// create separate, disentangled type parameters. The above example
|
||||||
// any problems of type parameter identity. For example, the following code
|
// can be rewritten into the following equivalent code:
|
||||||
// is equivalent to the code above.
|
|
||||||
//
|
//
|
||||||
// func f[P interface{*Q}, Q any](p P, q Q) {
|
// func f[P constraint](x P) {
|
||||||
// f2(p)
|
// f2(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func f2[P interface{*Q}, Q any](p P, q Q) {
|
// func f2[P2 constraint](x P2) {
|
||||||
// f(p)
|
// f(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// We turn the first example into the second example by renaming type
|
// Type parameter renaming turns the first example into the second
|
||||||
// parameters in the original signature to give them a new identity.
|
// example by renaming the type parameter P into P2.
|
||||||
tparams2 := make([]*TypeParam, len(tparams))
|
tparams2 := make([]*TypeParam, len(tparams))
|
||||||
for i, tparam := range tparams {
|
for i, tparam := range tparams {
|
||||||
tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
|
tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
|
||||||
|
@ -221,32 +221,31 @@ func (check *Checker) infer1(posn positioner, tparams []*TypeParam, targs []Type
|
|||||||
func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
|
func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
|
||||||
// For the purpose of type inference we must differentiate type parameters
|
// For the purpose of type inference we must differentiate type parameters
|
||||||
// occurring in explicit type or value function arguments from the type
|
// occurring in explicit type or value function arguments from the type
|
||||||
// parameters we are solving for via unification, because they may be the
|
// parameters we are solving for via unification because they may be the
|
||||||
// same in self-recursive calls. For example:
|
// same in self-recursive calls:
|
||||||
//
|
//
|
||||||
// func f[P *Q, Q any](p P, q Q) {
|
// func f[P constraint](x P) {
|
||||||
// f(p)
|
// f(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// In this example, the fact that the P used in the instantation f[P] has
|
// In this example, without type parameter renaming, the P used in the
|
||||||
// the same pointer identity as the P we are trying to solve for via
|
// instantation f[P] has the same pointer identity as the P we are trying
|
||||||
// unification is coincidental: there is nothing special about recursive
|
// to solve for through type inference. This causes problems for type
|
||||||
// calls that should cause them to conflate the identity of type arguments
|
// unification. Because any such self-recursive call is equivalent to
|
||||||
// with type parameters. To put it another way: any such self-recursive
|
// a mutually recursive call, type parameter renaming can be used to
|
||||||
// call is equivalent to a mutually recursive call, which does not run into
|
// create separate, disentangled type parameters. The above example
|
||||||
// any problems of type parameter identity. For example, the following code
|
// can be rewritten into the following equivalent code:
|
||||||
// is equivalent to the code above.
|
|
||||||
//
|
//
|
||||||
// func f[P interface{*Q}, Q any](p P, q Q) {
|
// func f[P constraint](x P) {
|
||||||
// f2(p)
|
// f2(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func f2[P interface{*Q}, Q any](p P, q Q) {
|
// func f2[P2 constraint](x P2) {
|
||||||
// f(p)
|
// f(x)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// We turn the first example into the second example by renaming type
|
// Type parameter renaming turns the first example into the second
|
||||||
// parameters in the original signature to give them a new identity.
|
// example by renaming the type parameter P into P2.
|
||||||
tparams2 := make([]*TypeParam, len(tparams))
|
tparams2 := make([]*TypeParam, len(tparams))
|
||||||
for i, tparam := range tparams {
|
for i, tparam := range tparams {
|
||||||
tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
|
tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user