naiveai
naiveai

Reputation: 853

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

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?

Upvotes: 3

Views: 478

Answers (1)

Brian61354270
Brian61354270

Reputation: 14434

Taking 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 implementation for Something::TEST as follows will compile as expected.

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

Note that this uses references to self.a and self.b.


The fact that operations like bitwise-or are only implemented for references to containers instead of for the the container types themselves may seem unexpected at first, but it makes perfect sense when you think about their expected ownership semantics. The signature of bitor is fn bitor(self, rhs: T), which takes ownership of both self and rhs. If BitOr (or any other binary operator trait) were implemented directory a type that isn't Copy, then it would be taking ownership of the arguments to |. Having a | b resulting in either a or b being moved would be rather unexpected. As such, the standard library only implements binary operators for references to collections (which are Copyable) rather than on collection values themselves.

Upvotes: 5

Related Questions