The following code doesn't compile while the same code with iter_mut instead of par_iter_mut compiles. Why do I need to implement the IntoParallelIterator trait, and how can I do that?
Thanks
use rayon::prelude::*;
trait E {fn eval(&self) -> f64;}
struct C<T:E> {
d : T,
v : f64}
type P<T> = Vec<C<T>>;
fn eval_test<T:E>(mut p:P<T>) -> P<T>{
//p.iter_mut().for_each(|v| v.v=v.d.eval());
p.par_iter_mut().for_each(|v| v.v= v.d.eval());
return p;
}
The compiler tells you exactly what the problem is: &mut Vec<T> / &mut [T] doesn't implement that trait. If you go look up that impl in the docs, you can see it requires that the element type T be thread-safe (T: Send). So you have to specify that bound on your function.
You can't. You can't implement a foreign (non-crate-local) trait for a foreign (non-crate-local) type.
FYI, The solution that @H2CO3 was suggesting AFAICT would be to put the bound onto the eval_test function, like fn eval_test<T:E+Send> (or alternatively separately as T: Send in a where clause.)
The difference is that trait E: Send means allE types must be thread-safe, whereas putting it on the function means it's only required if you're going to call that function.
Another consideration is that your function is only using the immutable &self, at least in this reduced example, so it could call par_iter() instead. That would shift your requirement to Sync, which could be easier to satisfy.
As far as I understand, when you declare a trait with a supertrait (like trait X: Y), then all where T: X clauses effectively become where T: X + Y automatically.
use rayon::prelude::*;
trait E {
fn eval(&self) -> f64;
}
struct C<T: E> {
d: T,
v: f64,
}
type P<T> = Vec<C<T>>;
fn eval_test<T>(mut p: P<T>) -> P<T>
where
T: E + Send, // if you had declared `trait E: Send`, then the `+ Send` would be implied here
{
p.par_iter_mut().for_each(|v| v.v = v.d.eval());
return p;
}
Interestingly, this only works with Supertraits (or where Self: Y bounds in the trait definition, which are just another syntax for supertraits), and not with any other bounds in the trait definition.