mirror of
https://github.com/golang/go
synced 2024-11-17 06:14:51 -07:00
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 <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
e7d5857a5a
commit
9284279b44
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user