]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: interface identity must consider full...
authorRobert Griesemer <gri@golang.org>
Sun, 11 Jul 2021 22:27:49 +0000 (15:27 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 14 Jul 2021 23:33:49 +0000 (23:33 +0000)
There is no (obvious) way to test this at the moment because we
don't permit such constraint interfaces as ordinary types.

Change-Id: Ieeec023ed82a2c71ed50d111f26916aba4a59099
Reviewed-on: https://go-review.googlesource.com/c/go/+/333889
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/unify.go

index 2f1089858576222c7b5a324bebfc6cb7599ab335..e862c0fca8ae9a2c70d18806e0eb2cc4981aedf4 100644 (file)
@@ -270,12 +270,21 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
                }
 
        case *Interface:
+               // Two interface types are identical if they describe the same type sets.
+               // With the existing implementation restriction, this simplifies to:
+               //
                // Two interface types are identical if they have the same set of methods with
-               // the same names and identical function types. Lower-case method names from
-               // different packages are always different. The order of the methods is irrelevant.
+               // the same names and identical function types, and if any type restrictions
+               // are the same. Lower-case method names from different packages are always
+               // different. The order of the methods is irrelevant.
                if y, ok := y.(*Interface); ok {
-                       a := x.typeSet().methods
-                       b := y.typeSet().methods
+                       xset := x.typeSet()
+                       yset := y.typeSet()
+                       if !Identical(xset.types, yset.types) {
+                               return false
+                       }
+                       a := xset.methods
+                       b := yset.methods
                        if len(a) == len(b) {
                                // Interface types are the only types where cycles can occur
                                // that are not "terminated" via named types; and such cycles
index 755622738a6fccde736032677c06b9122974e012..7221356354aca128a9f0134deaa4f3e1f296ce44 100644 (file)
@@ -362,16 +362,20 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
                }
 
        case *Union:
-               // This should not happen with the current internal use of union types.
-               panic("type inference across union types not implemented")
+               panic("unimplemented: unification with type sets described by types")
 
        case *Interface:
                // Two interface types are identical if they have the same set of methods with
                // the same names and identical function types. Lower-case method names from
                // different packages are always different. The order of the methods is irrelevant.
                if y, ok := y.(*Interface); ok {
-                       a := x.typeSet().methods
-                       b := y.typeSet().methods
+                       xset := x.typeSet()
+                       yset := y.typeSet()
+                       if !Identical(xset.types, yset.types) {
+                               return false
+                       }
+                       a := xset.methods
+                       b := yset.methods
                        if len(a) == len(b) {
                                // Interface types are the only types where cycles can occur
                                // that are not "terminated" via named types; and such cycles