Issue with async_trait and Send trait in Rust

Hello,
I'm currently working on a project where I'm using the async_trait crate to define async functions in traits. Here's a simplified version of my code:

use std::marker::PhantomData;

use async_trait::async_trait;

pub trait RT {
    fn return_type() -> String;
}

#[derive(Default)]
pub struct FunctionCall<R> {
    pub(crate) datatype: PhantomData<R>,
}

impl<R: RT> FunctionCall<R> {
    pub async fn call(&self) -> Result<R, String>{
        todo!()
    }
}

struct Wrapper {
    a: String
}

impl Wrapper {
    pub fn method<R: RT>() -> FunctionCall<R> {
        todo!()
    }
}

pub struct A {}

#[async_trait]
pub trait test_call{
    async fn try_call<R: RT + Send >(&self) -> Result<R, String>;
}

#[async_trait]
impl test_call for A {
    async fn try_call<R: RT + Send>(&self) -> Result<R, String>{
        Wrapper::method::<R>().call().await
    }
}

I'm getting an error that: future cannot be sent between threads safely
Interestingly, when I change the trait definition to R: RT + Send + Sync, the error goes away.

I would appreciate any help or guidance on why Sync is needed in this case and how the Send and Sync traits interact in the context of async functions and traits. Thanks in advance.

The async_trait crate simply defaults to requiring Send (which in turn makes the resulting Future Send). The reason is that often you want to spawn a Future that ultimately could contain yours. You can opt out of this by using the macro with an additonal ?Send argument, i.e. #[async_trait(?Send)], on both the trait and the impl. This is documented here

1 Like

Thank you for your response. so is it necessary to add the Sync constraint to R in order for the Future to be Send?

No, you don't need it. Generally speaking Futures don't care about Syncness of types, unless that Syncness influences the Sendness of another type (e.g. if your Future contains an Arc<T> then it cares only about Arc<T>: Send, but that in turn requires T: Sync + Send)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.