I have a Vec<ValidRelationshipTree> and I would like to use rayon's parallel iteration to process each tree in parallel. I cannot do so as my ValidRelationshipTree doesn't satisfy std::marker::Sized.
Definition of ValidRelationshipTree, whose size is clearly known at compile time:
// size = 16 (0x10), align = 0x8
struct ValidRelationshipTree {
root: RefCell<Rc<ValidRelationshipNode>>,
}
Compilation error:
the method `into_par_iter` exists for struct `Vec<ValidRelationshipTree>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`[metadata::relationships::ValidRelationshipTree]: std::marker::Sized`
which is required by `[metadata::relationships::ValidRelationshipTree]: rayon::iter::IntoParallelIterator`
`[metadata::relationships::ValidRelationshipTree]: rayon::iter::ParallelIterator`
which is required by `[metadata::relationships::ValidRelationshipTree]: rayon::iter::IntoParallelIterator`
Since my structure's size is known at compile time, I don't understand how std::marker::Sized isn't implemented. I've tried to read through this trait's documentation, researching similar rayon issues, but I just don't understand. I even tried creating a wrapper struct around my Vec<ValidRelationshipTree> but no dice.
If anyone could help fill in my gap of knowledge that would be greatly appreciated <3.
In case it's relevant, here is the definition of ValidRelationshipNode:
struct ValidRelationshipNode {
payload: String,
extended: String,
parent: RefCell<Weak<ValidRelationshipNode>>, // Use Weak<T> to avoid reference cycles
children: RefCell<Vec<Rc<ValidRelationshipNode>>>,
}
Concrete code example
The following sequential block compiles just fine:
let forest: Vec<ValidRelationshipTree> = self.generate_relationship_trees(n_tables, true);
let mut extended: Vec<String> = forest
.into_iter()
.flat_map(|tree: ValidRelationShipTree| {
tree.nodes_with_length(n_tables)
.into_iter()
.map(|node: Rc<ValidRelationshipNode>| node.extended().clone())
})
.collect();
And a trivial test case that errors:
let forest: Vec<ValidRelationshipTree> = self.generate_relationship_trees(n_tables, true);
let extended_par: Vec<String> = forest
.into_par_iter() // ERROR: the following trait bounds were not satisfied:
// [metadata::relationships::ValidRelationshipTree]: std::marker::Sized`
.map(|node| node.extended().clone())
.collect();
If you instead call
into_par_iteras an associated function onVec, you get a more helpful error:The simplest way to get around this is to use
Arcinstead ofRcandMutexorRwLockinstead ofRefCell.Then this code probably works, depending on the other functions involved: