I want to be able to compare two structs, when the structs contain a reference to a trait inside them. I only care about knowing that the two references are to the same memory location. My code compiles, runs, and shows that the two references are not equal. I expected them to be equal, so I have a bug. But my Debug impl shows that they are equal, so I'm confused.
I haven't been able to make a self-contained repo of my bug, but I can reproduce my Debug
problem:
#[derive(Debug, PartialEq)]
struct Intersection<'a> {
intersected: &'a dyn Intersectable,
}
trait Intersectable {}
impl<'a> core::fmt::Debug for dyn Intersectable + 'a {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Intersectable{{{:?}}}", core::ptr::addr_of!(self))
}
}
impl<'a> PartialEq for dyn Intersectable + 'a {
fn eq(&self, other: &Self) -> bool {
std::ptr::eq(self, other)
}
}
#[derive(Debug, PartialEq)]
struct Sphere {}
impl Intersectable for Sphere {}
#[test]
fn comparison_bug() {
let sphere = Sphere{};
let other = Sphere{};
let i = Intersection{ intersected: &sphere };
assert_eq!(i.intersected, &sphere as &dyn Intersectable);
assert_eq!(i.intersected, &other as &dyn Intersectable);
}
In the test, the assertion assert_eq!(i.intersected, &other as &dyn Intersectable);
fails. This is correct -- I'm looking at two different instances of a Sphere
struct, so the definitely are not equal.
The problem is that the message printed by assert_eq!
says
assertion failed: `(left == right)`
left: `Intersectable{0x7faebfa72188}`,
right: `Intersectable{0x7faebfa72188}`
This is no good. I'm trying to print the address of each reference, so left and right should be different addresses (as the test correctly determined!). Why is my Debug
printing the same address for both?
I also tried making my impl of PartialEq
into addr_of!(self) == addr_of(other)
and it behaves exactly the same (the test fails correctly but the Debug message appears to show that they are the same address).