]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: interface identity must consider full type set
authorRob Findley <rfindley@google.com>
Sat, 17 Jul 2021 00:46:39 +0000 (20:46 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 19 Jul 2021 17:09:20 +0000 (17:09 +0000)
This is a port of CL 333889 to go/types.

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

index c9be12183944fe744445ff94613db21909ad6396..ea2bed720a19ec75b2023d32ba133b3355ff7ca8 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 84c8ae718f0e64ba0dcf7a6471e69e06cdc24614..da57e533cc81b4f67688d4377b78c34c9ee48a51 100644 (file)
@@ -359,16 +359,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