8

I have a code that has a bug in one of the functions:

fn is_five(x: &i32) -> bool {
    x == 5
}

fn main() {
    assert!(is_five(&5));
    assert!(!is_five(&6));
    println!("Success!");
}

While running, the error is:

error[E0277]: can't compare `&i32` with `{integer}`
 --> main.rs:2:7
  |
2 |     x == 5
  |       ^^ no implementation for `&i32 == {integer}`
  |
  = help: the trait `std::cmp::PartialEq<{integer}>` is not implemented for `&i32`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

I fixed it by the logic of comparing two values and not one address and one value.

fn is_five(x: &i32) -> bool {
    *x == 5
}

However, I also tried (randomly) to use the borrowing method and to my surprise, it worked.

fn is_five(x: &i32) -> bool {
    x == &5
}

I do not understand how two addresses can be same? Is it that == operator has some trait that gets the value stored at both ends?

Aviral Srivastava
  • 4,058
  • 8
  • 29
  • 81
  • 1
    You may use [std::ptr::eq](https://doc.rust-lang.org/std/ptr/fn.eq.html) to compare pointers instead of values, just in case you'll need it. – Aunmag Feb 04 '21 at 10:48

1 Answers1

6

To be able to do ==, one must implement PartialEq. If you check the docs here, you can see that if a type A implements PartialEq<B> then &'_ A implements PartialEq<&'_ B>. In other words, if you can compare values, you can compare them using references.

The same reasoning applies for other comparison traits: Eq, PartialOrd, and Ord, and for mutable references.

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
Bromind
  • 1,065
  • 8
  • 23
  • 2
    "if you can compare values, you can compare their pointers" is slightly misleading because it's not the pointers that are being compared when you write `x == &5`, it's the values they point to. – user4815162342 Feb 04 '21 at 10:12
  • 1
    @user4815162342 Yes you're right. I would have been clearer to writn "if you can compare values, you can compare them using pointers to them". That being said, it is not false to say that, defining a partial order relation between values implies a partial order relation on pointers to that values. Thanks for the clarification. – Bromind Feb 04 '21 at 10:34
  • 2
    Note that you're not comparing pointers but references. [Comparing pointers will compare the pointers themselves and not the pointed values](https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=dd44ace432ba539fb288f44aa87eb266) – Jmb Feb 04 '21 at 10:55
  • 1
    @Jmb Thanks for the correction. For other users who find the distinction unclear, here is some more information : https://stackoverflow.com/questions/62232753/differences-between-a-pointer-and-a-reference-in-rust – Bromind Feb 04 '21 at 11:02