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).