-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic params from impl dont have 'async_trait lifetime #8
Comments
Thanks! I don't know how to fix this best, since I don't want to infer overly restrictive bounds by default -- it's always possible for the user of the macro to add extra bounds as necessary, but there isn't a good way for them to subtract bounds that aren't right. I found that inferring I would recommend adding your own #[async_trait]
pub trait MapInto<T>: Future {
async fn map_into(self) -> T
where
Self: Sized,
T: 'async_trait;
}
#[async_trait]
impl<F, T> MapInto<T> for F
where
F: ?Sized + Future + Send,
T: From<F::Output>,
{
async fn map_into(self) -> T
where
Self: Sized,
T: 'async_trait,
{
self.await.into()
}
} That bound basically means "
So for example, if the caller wants to get back a |
Then I will have to add a lot of Your solution works:
However it requires a lot of boilerplate... I need to figure out how to beautify it. |
FWIW, here is a more minimal example: #[async_trait::async_trait]
pub trait Trait<T> {
async fn foo() {
()
}
} Seeing as such a trivial example already fails the |
FYI: currently, it seems functions that return impl traits capture all generic type parameters in function's generics, whether they are actually used or not. (probably related to rfc1951) pub trait Trait<T> {
fn method<'lt>() -> Box<dyn ::core::fmt::Debug + 'lt>;
}
impl<T> Trait<T> for usize {
fn method<'lt>() -> Box<dyn ::core::fmt::Debug + 'lt> {
fn __method<'lt, T>() -> impl ::core::fmt::Debug + 'lt {}
Box::new(__method::<T>())
//~^ ERROR the parameter type `T` may not live long enough
}
} (EDIT: Seems generic type parameters of functions that return impl traits do not need explicit lifetime bounds because implied lifetime bounds.) In the current implementation of async-trait, the generated freestanding function's generics is impl's generics + method's generics, so it seems that all generic type parameters actually require (at least Also, this seems to be specific to generic type parameters of functions that return impl traits, for example, it doesn't apply to lifetime definitions of functions that return impl traits or generic type parameters of functions that return normal values. (I wrote this comment because I wasn't sure if #8 (comment) was written with this in mind. I'm sorry if I misread your comment.) |
I'm having a similar issue, but unfortunately this isn't as easily fixable: #[async_trait]
trait Trait {
async fn func(&self);
}
struct Struct<R>(R);
#[async_trait]
impl<R: Deref<Target = Option<T>> + Send + Sync, T: Send + Sync> Trait for Struct<R> {
async fn func(&self) {
// ^ [rustc E0309] [E] the parameter type `T` may not live long enough
}
} I can't add |
@Koxiaet A workaround that I know is adding lifetime to trait: playground |
I'm getting the same error, but with default impl directly in declaration: #[async_trait]
trait Trait <T: Send>: Struct {
async fn assoc_func<U>(n: Vec<T>) -> CustomResult<'_, Vec<U>> {
call_async_func().await
}
} Produces:
Addind #[async_trait]
trait Trait <T: 'async_trait + Send>: Struct {
async fn assoc_func<U>(n: Vec<T>) -> CustomResult<'_, Vec<U>> {
call_async_func().await
}
} Results in:
|
@dtolnay: I think this issue has been fixed by #143: playground |
Nice! |
Sadly, I'm still getting this issue, in a more complicated case (playground link, MRE below). The provided workaround of adding It seems to be some more complex interaction of types, because removing the use async_trait::async_trait;
use tokio::sync::mpsc;
#[async_trait]
trait InputStage<StageOutput>: Sized
where
StageOutput: Send,
{
async fn run(
mut self,
_output: mpsc::Sender<StageOutput>,
)
//where StageOutput: 'async_trait,
{
}
} |
I tried to produce a MRE:
A fix for me:
T: 'static,
in impl block. Is it a bug?The text was updated successfully, but these errors were encountered: