== cannot be applied to type HashSet

Hi, I wrote a wrapper for Hashset, and tried to compare two set with same elements. But compiler complained == cannot be applied to type HashSet even if I derived PartialEq(Hashset implement PartialEq and Eq traits).

Compiler suggest add #[derive(Debug, Eq, PartialEq + std::cmp::PartialEq)]. What's PartialEq + std::cmp::PartialEq mean? Thanks!

(playground)

use std::collections::HashSet;
use std::hash::Hash;

#[derive(Debug, PartialEq)]
pub struct CustomSet<T> {
    set: HashSet<T>,
}

impl<T> CustomSet<T>
where
    T: Eq + PartialEq + Hash + Copy,
{
    pub fn new(_input: &[T]) -> Self {
        let mut set: HashSet<T> = HashSet::new();
        for &i in _input {
            set.insert(i);
        }
        CustomSet { set }
    }
}

fn main() {
    let set1 = CustomSet::new(&[1, 2, 3]);
    let set2 = CustomSet::new(&[1, 2, 3]);
    assert_eq!(set1, set2);
    /*    let mut set1: HashSet<u32> = HashSet::new();
    set1.insert(1);
    let mut set2: HashSet<u32> = HashSet::new();
    set2.insert(1);
    assert_eq!(set1, set2);*/
}

error[E0369]: binary operation `==` cannot be applied to type `HashSet<T>`
 --> src\lib.rs:6:5
  |
6 |     set: HashSet<T>,
  |     ^^^^^^^^^^^^^^^
  |
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
  |
4 | #[derive(Debug, Eq, PartialEq + std::cmp::PartialEq)]
  |                               ^^^^^^^^^^^^^^^^^^^^^

HashSet has to hash its individual elements in order to compare its own contents to that of another HashSet. Therefore, you have to constrain the type parameter using the Hash trait bound in order to stand a chance of getting equality comparison to work for the set. Instead of deriving, try to implement the relevant traits manually:

impl<T> PartialEq for CustomSet<T>
    where
        T: Eq + Hash
{
    fn eq(&self, other: &Self) -> bool {
        self.set == other.set
    }
}

impl<T> Eq for CustomSet<T>
    where
        T: Eq + Hash
{
}
1 Like

That help suggestion looks like a compiler bug though…

2 Likes

Sure it does. The compiler seems to confuse the derive macro with the trait it is implementing. The suggestion is not even valid syntax.

1 Like

Thanks for reporting this @davyzhu!

2 Likes