aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/predicates.go
diff options
context:
space:
mode:
authorRobert Findley <rfindley@google.com>2021-11-22 12:47:53 -0500
committerRobert Findley <rfindley@google.com>2021-11-22 20:32:29 +0000
commit773f43b35638092f9c0dc56f4a468dce2eb3a8ef (patch)
tree7245582234f832258a7222ec8923da8d6a9c062b /src/cmd/compile/internal/types2/predicates.go
parent189b4a2f428be7264db76e5275c96d98b847383b (diff)
downloadgo-773f43b35638092f9c0dc56f4a468dce2eb3a8ef.tar.gz
go-773f43b35638092f9c0dc56f4a468dce2eb3a8ef.zip
go/types, types2: substitute for type parameters in signatures when
comparing type identity Generic signatures should be considered identical modulo type parameter renaming. Update Identical to reflect this, by substituting type parameters. Fixes #49722 Change-Id: I33743768c72d8aa59c29bf72fcbabc5974f0b805 Reviewed-on: https://go-review.googlesource.com/c/go/+/366178 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/types2/predicates.go')
-rw-r--r--src/cmd/compile/internal/types2/predicates.go72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/cmd/compile/internal/types2/predicates.go b/src/cmd/compile/internal/types2/predicates.go
index e7834a0f9e..cf2993f68b 100644
--- a/src/cmd/compile/internal/types2/predicates.go
+++ b/src/cmd/compile/internal/types2/predicates.go
@@ -235,19 +235,56 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
}
case *Signature:
- // Two function types are identical if they have the same number of parameters
- // and result values, corresponding parameter and result types are identical,
- // and either both functions are variadic or neither is. Parameter and result
- // names are not required to match.
- // Generic functions must also have matching type parameter lists, but for the
- // parameter names.
- if y, ok := y.(*Signature); ok {
- return x.variadic == y.variadic &&
- identicalTParams(x.TypeParams().list(), y.TypeParams().list(), cmpTags, p) &&
- identical(x.params, y.params, cmpTags, p) &&
- identical(x.results, y.results, cmpTags, p)
+ y, _ := y.(*Signature)
+ if y == nil {
+ return false
+ }
+
+ // Two function types are identical if they have the same number of
+ // parameters and result values, corresponding parameter and result types
+ // are identical, and either both functions are variadic or neither is.
+ // Parameter and result names are not required to match, and type
+ // parameters are considered identical modulo renaming.
+
+ if x.TypeParams().Len() != y.TypeParams().Len() {
+ return false
+ }
+
+ // In the case of generic signatures, we will substitute in yparams and
+ // yresults.
+ yparams := y.params
+ yresults := y.results
+
+ if x.TypeParams().Len() > 0 {
+ // We must ignore type parameter names when comparing x and y. The
+ // easiest way to do this is to substitute x's type parameters for y's.
+ xtparams := x.TypeParams().list()
+ ytparams := y.TypeParams().list()
+
+ var targs []Type
+ for i := range xtparams {
+ targs = append(targs, x.TypeParams().At(i))
+ }
+ smap := makeSubstMap(ytparams, targs)
+
+ var check *Checker // ok to call subst on a nil *Checker
+
+ // Constraints must be pair-wise identical, after substitution.
+ for i, xtparam := range xtparams {
+ ybound := check.subst(nopos, ytparams[i].bound, smap, nil)
+ if !identical(xtparam.bound, ybound, cmpTags, p) {
+ return false
+ }
+ }
+
+ yparams = check.subst(nopos, y.params, smap, nil).(*Tuple)
+ yresults = check.subst(nopos, y.results, smap, nil).(*Tuple)
}
+ return x.variadic == y.variadic &&
+ identical(x.params, yparams, cmpTags, p) &&
+ identical(x.results, yresults, cmpTags, p)
+
case *Union:
if y, _ := y.(*Union); y != nil {
xset := computeUnionTypeSet(nil, nopos, x)
@@ -389,19 +426,6 @@ func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool
return Identical(xorig, yorig)
}
-func identicalTParams(x, y []*TypeParam, cmpTags bool, p *ifacePair) bool {
- if len(x) != len(y) {
- return false
- }
- for i, x := range x {
- y := y[i]
- if !identical(x.bound, y.bound, cmpTags, p) {
- return false
- }
- }
- return true
-}
-
// Default returns the default "typed" type for an "untyped" type;
// it returns the incoming type for all other types. The default type
// for untyped nil is untyped nil.