Lifetime annotation in `func<T>(t:T) where &T : SomeTrait`

I have a trait as below

#[async_trait]
pub trait AsyncEvaluator {
    async fn evaluate(self, reducer : Arc<DebruijnInterpreter>, env : Env);
}

And this trait is implemented for types &mut T

#[async_trait]
impl AsyncEvaluator for &mut SomeStruct { }

Now I am trying to add a generic method as below

fn spawn_evaluation<'a, T>(t : T, reducer : Arc<DebruijnInterpreter>, env : Env) -> tokio::task::JoinHandle<()>
    where T : std::marker::Send + 'static,
        &'a mut T : AsyncEvaluator + std::marker::Send
{
    
    task::spawn( async move {
        let mut evaluator = t;
        let reference = &mut evaluator;
        reference.evaluate(reducer, env).await;
    })
}

I suppose t is moved into the async block, and call the evaluate() method on its mutable reference

mismatched types
expected type std::marker::Send
found type std::marker::SendrustcE0308
eval_par.rs(80, 21): the required lifetime does not necessarily outlive the lifetime 'a as defined on the function body at 80:21
spawn.rs(129, 21): the lifetime requirement is introduced here

eval_par.rs(80, 21): the required lifetime does not necessarily outlive the lifetime 'a as defined on the function body at 80:21

The task::spawn method is from tokio.

I think the problem is from &'a mut T, I tried &'_ mut T or &'static mut T, none of them works.

Please how should I fix this error?

Thank you

Anyway, I avoid this issue by changing the trait to

pub trait AsyncEvaluator {
    async fn evaluate(&mut self, reducer : Arc<DebruijnInterpreter>, env : Env);
}

And implement the trait on T instead of &mut T

The bound you probably wanted is:

where
    for<'a> &'a mut T : AsyncEvaluator + std::marker::Send
1 Like

Wow, the annotation can appear in that place :rofl: