Idea: Reference equality trait

Hi! I got an idea for a trait when working with Arc and Rc that I think might be useful. I'm still pretty new to Rust, and this is my first time ever suggesting something like this, so please be patient with me! Anyway, the trait is actually super simple:

pub trait RefEq<T> {
    fn ref_eq(self, other: T) -> bool;
    
    fn ref_ne(self, other: T) -> bool 
    where Self: Sized 
    {
        !self.ref_eq(other)
    }
}

It's basically just PartialEq. The intention here is to compare if two references "point" to the same allocation, i.e. two Rcs cloned from the same Rc would be "equal", but not to check for actual equality like PartialEq, hence it being a different trait. (And possibly another equality operator &==?) The trait could be automatically implemented for anything that impls Deref like so:

impl<T, U> RefEq<&U> for &T 
where T: core::ops::Deref<Target = U> + ?Sized,
      U: ?Sized
{
    fn ref_eq(self, other: &U) -> bool {
        (self.deref() as *const _) == (other as *const _)
    }
}

Any mutable references would always be not "equal", because there's no safe way to get two mutable references to the same location in memory at the same time.

Reference equality in my eyes is pretty niche but also useful to have. I originally got the idea when working with, Vec<Arc<T>>, I wanted to filter out Arcs that weren't equal by PartialEq but were equal by reference. My particular usecase was based on deduping a Vec, but I could see this having uses in allocators as well? I don't know nearly enough about the field to make a proper comment on that, though.

We do have Rc::ptr_eq and Arc::ptr_eq associated methods. Note that these are explicitly not self methods, so you can't call as myrc.ptr_eq(other), but rather Rc::ptr_eq(myrc, other).

1 Like

It would be nice if it was generalized under a trait. Plus, this could apply to shared references too?

What's the added value of abstracting over pointer equality rather than pointee equality (i.e. PartialEq and Eq)? That is, what problem does it solve that isn't catered to today?

2 Likes

You run into complications with ZSTs and trait objects. (Arc and Rc have their own non-zero allocation to refer to.)