When I try to derive(PartialEq) for type I get weird compilation error in generated code, but I'm sure it should be fine.
Here's link to playground
I simplified your example slightly to Box, and also changed to a manual impl, and it still fails:
struct Foo<T: ?Sized> {
value: T,
}
impl<T: ?Sized> PartialEq for Foo<T> {
fn eq(&self, _: &Self) -> bool { true }
}
trait Trait {}
struct Bar {
ptr: Box<Foo<dyn Trait>>,
}
impl PartialEq for Bar {
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
fn main() {}
error[E0507]: cannot move out of `other.ptr` which is behind a shared reference
--> src/main.rs:17:21
|
17 | self.ptr == other.ptr
| ^^^^^^^^^ move occurs because `other.ptr` has type `std::boxed::Box<Foo<dyn Trait>>`, which does not implement the `Copy` trait
If you change Foo<dyn Trait> to Foo<Trait>, this can even be reproduced on really old versions of Rust, all the way back to 1.1 -- however Rust 1.0 accepts it!
Changing to &self.ptr == &other.ptr works. PartialEq for & just calls UFCS, which also works here, Foo::eq(&self.ptr, &other.ptr). But of course you can't make #[derive(PartialEq)] do that.
It does work generically, even instantiated with the same type:
// Foo and Trait as before
struct Bar<T: ?Sized> {
ptr: Box<Foo<T>>,
}
impl<T: ?Sized> PartialEq for Bar<T> {
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
fn eq(a: Bar<dyn Trait>, b: Bar<dyn Trait>) -> bool {
a == b
}
I went nightly-bisecting -- it works on nightly-2015-05-13, and fails on 2015-05-14.
$ rustc +nightly-2015-05-13 -Vv
rustc 1.1.0-nightly (c2b30b86d 2015-05-12) (built 2015-05-13)
binary: rustc
commit-hash: c2b30b86df6b34ba19e87e63402e43d9e81a64fb
commit-date: 2015-05-12
build-date: 2015-05-13
host: x86_64-unknown-linux-gnu
release: 1.1.0-nightly
$ rustc +nightly-2015-05-13 issue67369.rs
issue67369.rs:1:1: 3:2 warning: struct is never used: `Foo`, #[warn(dead_code)] on by default
issue67369.rs:1 struct Foo<T: ?Sized> {
issue67369.rs:2 value: T,
issue67369.rs:3 }
issue67369.rs:2:5: 2:13 warning: struct field is never used: `value`, #[warn(dead_code)] on by default
issue67369.rs:2 value: T,
^~~~~~~~
issue67369.rs:11:1: 13:2 warning: struct is never used: `Bar`, #[warn(dead_code)] on by default
issue67369.rs:11 struct Bar {
issue67369.rs:12 ptr: Box<Foo<Trait>>,
issue67369.rs:13 }
$ rustc +nightly-2015-05-14 -Vv
rustc 1.1.0-nightly (e5394240a 2015-05-14) (built 2015-05-14)
binary: rustc
commit-hash: e5394240a295650b567aa406b4a0e1e3a6749a5f
commit-date: 2015-05-14
build-date: 2015-05-14
host: x86_64-unknown-linux-gnu
release: 1.1.0-nightly
$ rustc +nightly-2015-05-14 issue67369.rs
issue67369.rs:17:21: 17:26 error: cannot move out of borrowed content
issue67369.rs:17 self.ptr == other.ptr
^~~~~
error: aborting due to previous error
That 1.0-compatible test source again:
struct Foo<T: ?Sized> {
value: T,
}
impl<T: ?Sized> PartialEq for Foo<T> {
fn eq(&self, _: &Self) -> bool { true }
}
trait Trait {}
struct Bar {
ptr: Box<Foo<Trait>>,
}
impl PartialEq for Bar {
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
fn main() {}
Most helpful comment
I went nightly-bisecting -- it works on nightly-2015-05-13, and fails on 2015-05-14.
Comparison: https://github.com/rust-lang/rust/compare/c2b30b86df6b34ba19e87e63402e43d9e81a64fb...e5394240a295650b567aa406b4a0e1e3a6749a5f
That 1.0-compatible test source again: