Rust complains that BitOr isn't implemented for a HashSet when performing a union, docs state it should be

Viewed 230

Minimum example:

use std::collections::HashSet;

struct Something {
    a: HashSet<Point>,
    b: HashSet<Point>
}

impl Something {
    fn TEST(&self) {
        let new = self.a | self.b;
    }
}

#[derive(Eq, PartialEq, Hash, Copy, Clone)]
struct Point {
    x: usize,
    y: usize
}

Check it on the Rust Playground. If you try and compile this code, Rust will complain with error[E0369]: no implementation for std::collections::HashSet<Point> | std::collections::HashSet<Point>.

But according to the docs for HashSet, at least according to my understanding, the BitOr trait should be implemented for a HashSet, where T: Eq + Hash + Clone, which Point clearly is here. So what's actually going on, and how do I fix it?

1 Answers

Take a closer look at the implemention of BitOr for HashSet:

impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
where
   ...

BitOr is only implemented for references to HashSets, not for owned values.

Re-writing your implemented for Something::TEST as follows will compile as expected.

impl Something {
    fn TEST(&self) {
        let new = &self.a | &self.b;
    }
}

Note that we use references to self.a and self.b.

Related