diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go index c9be121839..ea2bed720a 100644 --- a/src/go/types/predicates.go +++ b/src/go/types/predicates.go @@ -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 diff --git a/src/go/types/unify.go b/src/go/types/unify.go index 84c8ae718f..da57e533cc 100644 --- a/src/go/types/unify.go +++ b/src/go/types/unify.go @@ -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