From f05c1941dd386217bd7c199c13be35a806fdd514 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 12 Apr 2023 09:43:41 -0700 Subject: [PATCH] go/types, types2: generalize tparamIndex to arbitrary type parameter lists tparamIndex returns the index of a type parameter given the type parameter and a list of type parameters. If an index >= 0 is returned, it is the index assigned to the type parameter (TypeParam.index), and the index of the type parameter in the provided list of parameters. For it to work correctly, the type parameter list must be from a single type parameter declaration. To allow for lists of arbitrary type parameters (from different generic signatures), change the implementation to do a linear search. The result is the index of the type parameter in the provided type parameter list, which may be different from the index assigned to the type parameter. The linear search is likely fast enough since type parameter lists tend to be very short. Change-Id: I913f97fa4c042abeb535ee86ca6657241a4cf796 Reviewed-on: https://go-review.googlesource.com/c/go/+/483995 Reviewed-by: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Robert Findley Auto-Submit: Robert Griesemer TryBot-Result: Gopher Robot --- src/cmd/compile/internal/types2/infer.go | 16 ++++++---------- src/go/types/infer.go | 16 ++++++---------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go index ed11ae8e4c7..ee2bcf79e4f 100644 --- a/src/cmd/compile/internal/types2/infer.go +++ b/src/cmd/compile/internal/types2/infer.go @@ -694,17 +694,13 @@ func (w *cycleFinder) varList(list []*Var) { } } -// If tpar is a type parameter in list, tparamIndex returns the type parameter index. -// Otherwise, the result is < 0. tpar must not be nil. +// If tpar is a type parameter in list, tparamIndex returns the index +// of the type parameter in list. Otherwise the result is < 0. func tparamIndex(list []*TypeParam, tpar *TypeParam) int { - // Once a type parameter is bound its index is >= 0. However, there are some - // code paths (namely tracing and type hashing) by which it is possible to - // arrive here with a type parameter that has not been bound, hence the check - // for 0 <= i below. - // TODO(rfindley): investigate a better approach for guarding against using - // unbound type parameters. - if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar { - return i + for i, p := range list { + if p == tpar { + return i + } } return -1 } diff --git a/src/go/types/infer.go b/src/go/types/infer.go index c2138f4a36b..0f8e7aeddcc 100644 --- a/src/go/types/infer.go +++ b/src/go/types/infer.go @@ -696,17 +696,13 @@ func (w *cycleFinder) varList(list []*Var) { } } -// If tpar is a type parameter in list, tparamIndex returns the type parameter index. -// Otherwise, the result is < 0. tpar must not be nil. +// If tpar is a type parameter in list, tparamIndex returns the index +// of the type parameter in list. Otherwise the result is < 0. func tparamIndex(list []*TypeParam, tpar *TypeParam) int { - // Once a type parameter is bound its index is >= 0. However, there are some - // code paths (namely tracing and type hashing) by which it is possible to - // arrive here with a type parameter that has not been bound, hence the check - // for 0 <= i below. - // TODO(rfindley): investigate a better approach for guarding against using - // unbound type parameters. - if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar { - return i + for i, p := range list { + if p == tpar { + return i + } } return -1 }