Predicates such as FnPredicate use PhantomData<T> to bypass the requirement that all generic parameters must be used. This makes the compiler think that predicate owns an instance of T, leading to two effects:
if T is bound by lifetime 'a, then the predicate will also be bound by 'a,
if T is not Send or Sync, the predicate will also not be Send or Sync.
There's nothing we can do about the first one. The second one, however, can be remedied by manually implementing Send and Sync.
For FnPredicate it will look like this:
unsafe impl<F, T> Send for FnPredicate<F, T>
where
F: Fn(&T) -> bool + Send,
T: ?Sized,
{
}
unsafe impl<F, T> Sync for FnPredicate<F, T>
where
F: Fn(&T) -> bool + Sync,
T: ?Sized,
{
}
This change will add unsafe to the crate. The benefit is that predicates will be easier to use in multi-threaded environments.
Predicates such as
FnPredicate
usePhantomData<T>
to bypass the requirement that all generic parameters must be used. This makes the compiler think that predicate owns an instance ofT
, leading to two effects:T
is bound by lifetime'a
, then the predicate will also be bound by'a
,T
is notSend
orSync
, the predicate will also not beSend
orSync
.There's nothing we can do about the first one. The second one, however, can be remedied by manually implementing
Send
andSync
.For
FnPredicate
it will look like this:This change will add
unsafe
to the crate. The benefit is that predicates will be easier to use in multi-threaded environments.