dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.81k stars 84 forks source link

Future is not 'Sync' as this value is used across an await #219

Closed eldenpark closed 1 year ago

eldenpark commented 1 year ago

I came across this issue a few days back and I can't seem to figure out what the cause of it is in the first place let alone how to deal with it.

I'm invoking an async method that in itself calls another async method of a struct (async-trait constrained method). It says 'future' is not Sync, and I tried with every possible dyn Trait + Send + Sync, unsafe impl Send/Sync bandage wherever possible to no avail. Could somebody give me a clue as to where this issue is coming from?

EDIT That driver method is type constrained inside

type Handler = Box<dyn Fn() -> Pin<Box<dyn Future<Output = Response<Body>> + Send + Sync + 'static>>
        + Send
        + Sync
        + 'static>;

// So, as in
Box::new(|| {
    Box::pin(driver.driver_func())
});
[async_trait::async_trait]
pub trait AsyncTrait {
    fn async_func(&self);
}

pub trait AsyncTraitObj;

[async_trait::async_trait]
impl AsyncTrait for AsyncTraitObj {
     fn async_func(&self) {}
}

struct Outer {
    trait_object: Arc<dyn AsyncTrait + Send + Sync>,
}

impl Outer {
    pub fn outer_func(&self) {
        self.trait_object.async_func().await;   // warning (cause of error): future is not 'Sync' as this value is used across an await
    }
}

struct Driver {
    pub fn driver_func(&self) {
        self.outer.outer_func().await; // Trigger method
    }
}
eldenpark commented 1 year ago

It turns out this wasn't the fault of "async-trait". Check out my question answered at the rust lang forum (https://users.rust-lang.org/t/future-is-not-sync-when-calling-async-fn-of-dyn-trait-obj-in-another-async-fn/83285/4) for those curious. Closing this issue.