2

I have this struct wrapping a Vec for which I implemented PartialEq following the solution proposed by this post

pub struct List<T> {
    memory:  Vec<T>,
}

impl<T> List<T> {
    pub fn new() -> Self {
        List {
            memory: Vec::new(),
        }
    }
    // push() add to end of list
    pub fn push(&mut self, value: T) {
        self.memory.push(value);
    }
}

impl<T, U> PartialEq<U> for List<T>
    where Vec<T>: PartialEq<U>
{
    fn eq(&self, other: &U) -> bool {
        &self.memory == other
    }
}

impl<T> PartialEq<List<T>> for Vec<u32>
    where T: PartialEq<u32>
{
    fn eq(&self, other: &List<T>) -> bool {
        &other.memory == self
    }
}

/* COMMENTED BECAUSE IT DOESN'T COMPILE
impl<T, U> PartialEq<List<T>> for Vec<U>
    where T: PartialEq<U>
{
    fn eq(&self, other: &List<T>) -> bool {
        &other.memory == self
    }
}
*/

fn main() {
    let mut listex: List<u32> = List::new();

    listex.push(17);
    listex.push(18);
    listex.push(19);
    listex.push(20);            

    println!("{}", listex == vec![17, 18, 19, 20]);
    println!("{}", vec![17, 18, 19, 20] == listex);
}

playground

It compiles and works

    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/tests`
true
true

But to implement the reverse == (i.e. be able to do both listex == vec![1,2] and vec![1,2] == listex) I have to specifically implement PartialEq for Vec<u32> and can't use a generic parameter as I get the following compiler error (uncommenting the PartialEq<List<T>> for Vec<U> bloc)

error[E0210]: type parameter `U` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
  --> src/main.rs:25:1
   |
25 | / impl<T, U> PartialEq<List<T>> for Vec<U>
26 | |     where T: PartialEq<U>
27 | | {
28 | |     fn eq(&self, other: &List<T>) -> bool {
29 | |         &other.memory == self
30 | |     }
31 | | }
   | |_^

Except for macros, is there an efficient way to implement all (or many of) the possible PartialEq to enable the reverse PartialEq?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
Boris
  • 991
  • 1
  • 9
  • 15
  • 1
    I think this is [orphan rules](https://doc.rust-lang.org/error-index.html#E0210) violation? you can't implement traits generically over types defined outside your own modules – fbstj May 18 '17 at 08:46
  • It is indeed. Thanks @fbstj for the link – Boris May 18 '17 at 20:57
  • maybe try implementing one of `From` or `Into` to convert `Vec` into `List` and then implement the 'backwards' `PartialEq` on that bounds? – fbstj May 19 '17 at 07:31

0 Answers0