The problem isn't the derive
, it's dyn PartialEq
.
The trick is that PartialEq
is actually shorthand for PartialEq<Self>
. So, with dyn PartialEq<Self>
, what's Self
? You don't know; it's whatever the dynamic type is!
If you remove the dummy trait A
(which I'm fairly sure was added to address this error), the error is a bit clearer:
error[E0393]: the type parameter `Rhs` must be explicitly specified
--> src/lib.rs:1:21
|
1 | fn check(_: Box<dyn PartialEq>) {}
| ^^^^^^^^^ help: set the type parameter to the desired type: `PartialEq<Rhs>`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
So what you want probably looks something like instead
trait DynPartialEq {
fn eq(&self, other: &dyn DynPartialEq) -> bool;
}
but... how do you implement such a trait? The only things you could do are compare pointer equality or just infinitely recurse calling other.eq(self)
.
The way dyn-clone
works is that it has a fn clone(&self) -> Box<dyn Trait>
method. The equivalent dyn-eq
would in fact be fn eq(&self, that: &dyn Trait) -> bool
, and implementing such requires the use of Any
to downcast.
So it could look something like
trait A: Any {
fn as_any(&self) -> &dyn Any;
fn eq(&self, that: &dyn A) -> bool;
}
impl PartialEq for dyn A {
fn eq(&self, that: &dyn A) -> bool {
A::eq(self, that)
}
}
// example
impl<T: Any> A for T {
fn as_any(&self) -> &dyn Any {
self
}
fn eq(&self, that: &dyn A) -> bool {
if let Some(that) = that.as_any().downcast_ref::<Self>() {
self.eq(that)
} else {
false
}
}
}
... but this doesn't quite work as-is because of something odd with the auto[de]ref rules. (The derive expansion thinks it needs to take the boxes by value for some reason.)