From 62f6f130fe1c6cbe9d2c1ea5160e83fb1cfa208a Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Fri, 16 Jul 2021 20:46:39 -0400 Subject: [PATCH] [dev.typeparams] go/types: interface identity must consider full type set 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 Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/go/types/predicates.go | 17 +++++++++++++---- src/go/types/unify.go | 12 ++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) 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