1

I am trying to make my own custom typed pointer but I can't seem to make it comparable. I narrowed my code to this:

use std::marker::PhantomData;

#[derive(PartialEq, Copy, Clone)]
pub struct PhantomPair<PHANTOM, REAL: Copy + Clone + PartialEq> {
    real: REAL,
    phantom: PhantomData<PHANTOM>,
}

impl<PHANTOM, REAL: Copy + Clone + PartialEq> PhantomPair<PHANTOM, REAL> {
    pub fn new(data: REAL) -> Self {
        PhantomPair {
            real: data,
            phantom: PhantomData,
        }
    }
}

fn is_eq<PHANTOM, REAL: Copy + Clone + PartialEq>(
    a: PhantomPair<PHANTOM, REAL>,
    b: PhantomPair<PHANTOM, REAL>,
) -> bool {
    a == b
}

fn main() {}

The compiler gives the following error:

error[E0369]: binary operation `==` cannot be applied to type `PhantomPair<PHANTOM, REAL>`
  --> src/main.rs:22:5
   |
22 |     a == b
   |     ^^^^^^
   |
   = note: an implementation of `std::cmp::PartialEq` might be missing for `PhantomPair<PHANTOM, REAL>`

I expected PhantomPair to have a derived PartialEq that uses REAL's PartialEq. As far as I know, PhantomData also implements PartialEq basically assuming equality.

The same issue happens when I try to add PartialOrd to #[derive] and to REAL's constraints.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
LOST
  • 2,956
  • 3
  • 25
  • 40
  • 1
    Don't use `SCREAMING_SNAKE_CASE` names for type parameters. Type parameters are `UpperCamelCase`, just like types. – Shepmaster May 01 '18 at 17:33
  • 1
    This is going to be a duplicate of [Deriving a trait results in unexpected compiler error, but the manual implementation works](https://stackoverflow.com/q/39415052/155423), although I don't know why the error message isn't as useful in this case. [The duplicate applied to your situation](https://play.rust-lang.org/?gist=9586c90883274c6ffbae98ac6bdc450f&version=stable&mode=debug). – Shepmaster May 01 '18 at 17:40
  • 1
    @Shepmaster Could it be just from the fact that this case uses the `==` operator instead of calling the method directly? – E_net4 May 01 '18 at 18:01
  • @E_net4 hmm, [that certainly looks possible](https://play.rust-lang.org/?gist=186e273167ce4c983bbde92529d7d6a0&version=stable&mode=debug). I'll see if I can't rustle up a bug report for that. – Shepmaster May 01 '18 at 18:19
  • I wonder if `PhantomData` ever implements equality, and whether `is_eq` should just do `a.real == b.real`. AFAICT, the `.phantom` member does not really exist, so it can't be compared. – 9000 May 01 '18 at 18:27
  • 1
    @9000 There's no need to wonder, the [documentation answers your question](https://doc.rust-lang.org/std/marker/struct.PhantomData.html#impl-PartialEq%3CPhantomData%3CT%3E%3E). – Shepmaster May 01 '18 at 18:40
  • I opened [Rust issue 50375](https://github.com/rust-lang/rust/issues/50375) to discuss the not-awesome error message. – Shepmaster May 01 '18 at 18:41

0 Answers0