Anaphory
Anaphory

Reputation: 6400

Rust claims DashMap into_par_iter trait bounds not satisfied

For some time, my Rust program used a DashMap with a parallel iterator bridge. This was a major performance bottleneck, and I have just found that these days, DashMap supposedly supports direct parallel iteration. So I updated my dependency crates and changed my code. Now I have my DashMap<K, V, S> like this

let families_by_location: DashMap<
    petgraph::graph::NodeIndex<usize>,
    Vec<&mut Family>,
    std::hash::BuildHasherDefault<FxHasher>,
> = DashMap::default();

families_by_location.into_par_iter().map(...).collect();

However, this does not compile, and surprisingly, the error message is very unhelpful for me.

error[E0599]: the method `into_par_iter` exists for struct `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>`, but its trait bounds were not satisfied
   --> src/lib.rs:442:10
    |
442 |         .into_par_iter()
    |          ^^^^^^^^^^^^^ method cannot be called on `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>` due to unsatisfied trait bounds
    |
   ::: /home/gereon/.cargo/registry/src/github.com-1ecc6299db9ec823/dashmap-5.2.0/src/lib.rs:67:1
    |
67  | pub struct DashMap<K, V, S = RandomState> {
    | -----------------------------------------
    | |
    | doesn't satisfy `_: rayon::iter::IntoParallelIterator`
    | doesn't satisfy `_: rayon::iter::ParallelIterator`
    |
    = note: the following trait bounds were not satisfied:
            `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `dispersal_model_rust` due to previous error

I also tried families_by_location.par_iter_mut() for a similarly unhelpful error concerning trait bounds.

I don't understand the issue. The trait bounds on DashMap<K, V, S> being an IntoParallelIterator are K: Send + Eq + Hash, V: Send, S: Send + Clone + BuildHasher. K is NodeIndex<usize>, which implements Send + Sync + Eq + Hash because usize does. The FxHasher Builder supposedly also supports Send + Sync + Clone + BuildHasher, and Vec is Send + Sync if its object type is. Now I would understand it if &mut Family is not Send, sending around mutable pointers between threads sounds dangerous. However, something like

let a: Vec<&mut Family> = families.par_iter_mut().collect();
let b: &dyn Sync = &a;

does no throw a compilation error, so it seems that Vec<&mut Family> is actually Send + Sync.

So it seems to me that the trait bounds for DashMap<K, V, S>: IntoParallelIterator trait bounds are fulfilled, why do I get the Rust compiler error?

Upvotes: 0

Views: 1227

Answers (1)

Anaphory
Anaphory

Reputation: 6400

An old comment on the DashMap issue tracker, which I found when searching for “parallel” on there, pointed out to me that activating the rayon feature is necessary. I did, and lo and behold my code compiles.

(I still find the error message which I get when not doing it quite confusing.)

While the list of feature flags on dashmap's docs.rs page states

rayon


This feature flag does not enable additional features.

that statement is a bit misleading: As Kevin Reid pointed out, “unlike most of rustdoc and docs.rs content, there is no automatic reporting of what a feature flag does, except for enabling other feature flags.” So all this statement only means is that activating dashmap's rayon feature does not activate other feature flags.

Upvotes: 0

Related Questions