From 9284279b44418b52221b4d68d400fa9220521726 Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Wed, 19 Jan 2022 22:00:42 -0500 Subject: [PATCH] go/types, types2: use Identical rather than unification in missingMethod Now that we instantiate methods on instantiated types, there is no need to use unification to match signatures inside of missingMethod. Generally, we should never encounter uninstantiated signatures within statements. If we do encounter signatures that contain type parameters, it is because the signatures are themselves defined or instantiated using type parameters declared in the function scope (see example below). The current unification logic would not handle this. type S[T any] struct{} func (S[T]) m(T) func _[P any]() bool { var v interface{m(int)} _, ok = v.(S[P]) return ok } Change-Id: I754fb5535bba2fc7a209dc7419fd4015c413c9a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/379540 Trust: Robert Findley Run-TryBot: Robert Findley Reviewed-by: Robert Griesemer TryBot-Result: Gopher Robot --- src/cmd/compile/internal/types2/lookup.go | 31 ++--------------------- src/go/types/lookup.go | 18 ++----------- 2 files changed, 4 insertions(+), 45 deletions(-) diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go index 61e8aa5054..3e55c07b67 100644 --- a/src/cmd/compile/internal/types2/lookup.go +++ b/src/cmd/compile/internal/types2/lookup.go @@ -328,14 +328,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, panic("method with type parameters") } - // If the methods have type parameters we don't care whether they - // are the same or not, as long as they match up. Use unification - // to see if they can be made to match. - // TODO(gri) is this always correct? what about type bounds? - // (Alternative is to rename/subst type parameters and compare.) - u := newUnifier(true) - u.x.init(ftyp.TypeParams().list()) - if !u.unify(ftyp, mtyp) { + if !Identical(ftyp, mtyp) { return m, f } } @@ -388,27 +381,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, panic("method with type parameters") } - // If the methods have type parameters we don't care whether they - // are the same or not, as long as they match up. Use unification - // to see if they can be made to match. - // TODO(gri) is this always correct? what about type bounds? - // (Alternative is to rename/subst type parameters and compare.) - u := newUnifier(true) - if ftyp.TypeParams().Len() > 0 { - // We reach here only if we accept method type parameters. - // In this case, unification must consider any receiver - // and method type parameters as "free" type parameters. - assert(acceptMethodTypeParams) - // We don't have a test case for this at the moment since - // we can't parse method type parameters. Keeping the - // unimplemented call so that we test this code if we - // enable method type parameters. - unimplemented() - u.x.init(append(ftyp.RecvTypeParams().list(), ftyp.TypeParams().list()...)) - } else { - u.x.init(ftyp.RecvTypeParams().list()) - } - if !u.unify(ftyp, mtyp) { + if !Identical(ftyp, mtyp) { return m, f } } diff --git a/src/go/types/lookup.go b/src/go/types/lookup.go index d35e53aa10..cc6be7493c 100644 --- a/src/go/types/lookup.go +++ b/src/go/types/lookup.go @@ -320,14 +320,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, panic("method with type parameters") } - // If the methods have type parameters we don't care whether they - // are the same or not, as long as they match up. Use unification - // to see if they can be made to match. - // TODO(gri) is this always correct? what about type bounds? - // (Alternative is to rename/subst type parameters and compare.) - u := newUnifier(true) - u.x.init(ftyp.TypeParams().list()) - if !u.unify(ftyp, mtyp) { + if !Identical(ftyp, mtyp) { return m, f } } @@ -375,14 +368,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, panic("method with type parameters") } - // If the methods have type parameters we don't care whether they - // are the same or not, as long as they match up. Use unification - // to see if they can be made to match. - // TODO(gri) is this always correct? what about type bounds? - // (Alternative is to rename/subst type parameters and compare.) - u := newUnifier(true) - u.x.init(ftyp.RecvTypeParams().list()) - if !u.unify(ftyp, mtyp) { + if !Identical(ftyp, mtyp) { return m, f } } -- 2.50.0