2

I've recently came across this in the Rust documentation about the implementation of PartialEq for Rc:

/// If `T` also implements `Eq` (implying reflexivity of equality),
/// two `Rc`s that point to the same allocation are
/// never unequal.

Surely by definition two pointers pointing two the same position in memory are equal (because they are the same value)? Why would this not be the case if two values are only PartialEq and not Eq?

mcarton
  • 27,633
  • 5
  • 85
  • 95
Teymour
  • 1,832
  • 1
  • 13
  • 34
  • Probably related: [Why does Rust not implement total ordering via the Ord trait for f64 and f32?](https://stackoverflow.com/q/26489701/1889329) – IInspectable Jul 20 '20 at 13:32

2 Answers2

2

Rust's pointer comparison don't compare the pointers, but the pointed-to values. This is the case for &T, &mut T, Box<T>, Rc<T>, Arc<T>, etc., all but the raw pointers *const T and *mut T themselves. Those smart pointers usually have an extra method (std::rc::Rc::ptr_eq in this case) for actual pointer comparison.

This is similar to how Debug on those pointers prints the pointed-to value rather than the address, and you need the Pointer trait to print the actual address: Rust isn't very address-focused.

Now, if you have a type such as f64 which doesn't have a transitive == (that is, it implements PartialEq but not Eq) and wrap it in an Rc, you also get non-transitivity:

fn main() {
    let a = std::rc::Rc::new(std::f64::NAN);

    println!("a == a?: {}", a == a);
    println!(
        "a == a but with pointer comparison?: {}",
        std::rc::Rc::ptr_eq(&a, &a)
    );

    // But:
    let answer = std::rc::Rc::new(42);
    // surely this will have a different address
    let another_answer = std::rc::Rc::new(42);

    println!("answer == another_answer?: {}", answer == another_answer);
}

prints:

a == a?: false
a == a but with pointer comparison?: true
answer == another_answer?: true

If T happens to implement Eq as well as PartialEq, the current implementation indeed does a pointer comparison, using the yet-to-be-stabilized specialization feature.

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
mcarton
  • 27,633
  • 5
  • 85
  • 95
  • 1
    See also [Is there a way to distingush between different `Rc`s of the same value?](https://stackoverflow.com/q/37706596/155423); [How to check if two variables point to the same object in memory?](https://stackoverflow.com/q/39463760/155423); [Why can comparing two seemingly equal pointers with == return false?](https://stackoverflow.com/q/47489449/155423). – Shepmaster Jul 20 '20 at 14:29
0

Because not all values are equal to themselves. NaN, for example.

Emerson Harkin
  • 889
  • 5
  • 13