Skip to content
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

using async_trait in tuple generic param, error: lifetime may not live long enough #242

Open
zavakid opened this issue Mar 19, 2023 · 2 comments

Comments

@zavakid
Copy link

zavakid commented Mar 19, 2023

hi, here is the code, and will compile for (A,), but can't compile for (A, B).

here is the code in the playgoround

use async_trait::async_trait;

struct Text;

#[async_trait]
trait FromText<'r> {
    type Output;
    async fn parse(text: &'r Text) -> Self::Output;
}

// can compile for (A,)
#[async_trait]
impl<'r, A> FromText<'r> for (A,)
where
    A: FromText<'r>,
{
    type Output = (A::Output,);

    async fn parse(text: &'r Text) -> Self::Output {
        let a = A::parse(text).await;
        (a,)
    }
}


// can't compile for (A, B)
#[async_trait]
impl<'r, A, B> FromText<'r> for (A, B)
where
    A: FromText<'r>,
    B: FromText<'r>,
    A::Output: Send,
    B::Output: Send,
{
    type Output = (A::Output, B::Output);

    async fn parse(text: &'r Text) -> Self::Output {
        let a = A::parse(text).await;
        let b = B::parse(text).await;
        (a, b)
    }
}

the error message:

ompiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
  --> src/lib.rs:37:52
   |
28 |   impl<'r, A, B> FromText<'r> for (A, B)
   |        -- lifetime `'r` defined here
...
37 |       async fn parse(text: &'r Text) -> Self::Output {
   |  ____________________________________________________^
38 | |         let a = A::parse(text).await;
39 | |         let b = B::parse(text).await;
40 | |         (a, b)
41 | |     }
   | |_____^ cast requires that `'r` must outlive `'static`
@jackalchenxu
Copy link

please use special lifetime 'async_trait, instead of 'r in declaration your trait FromText
to mark out the input text is always outlive in whole parse async blocks.

here is the compilable code

@zavakid
Copy link
Author

zavakid commented Mar 19, 2023

@jackalchenxu here I use 'r in the FromText because I want to impl for some reference, e.g. I can impl FromText for &str like below:

impl <'r> FromText<'r> for &str {
  type Output = &'r str;
  async fn parse(text: &'r Text) -> Self::Output  {
     // get string ref from text
  }
}

but how can I do above if I change the trait declaration?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants