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

Compilation error when using lifetime annotations with #[from] #68

Closed
lunacookies opened this issue Mar 21, 2020 · 2 comments · Fixed by #69
Closed

Compilation error when using lifetime annotations with #[from] #68

lunacookies opened this issue Mar 21, 2020 · 2 comments · Fixed by #69

Comments

@lunacookies
Copy link

Hi,

I’ve just run into an issue with thiserror. It may just be my inexperience with Rust’s lifetimes, though. The issue occurred when I was trying to use the #[from] attribute on an error that requires a lifetime specifier. I managed to create a minimal working example:

fn main() -> Result<(), Error<'static>> {
    Err(Error::SubError(SubError::Variant("some text")))
}

#[derive(Debug, thiserror::Error)]
enum Error<'a> {
    #[error("sub error")]
    SubError(#[from] SubError<'a>),
}

#[derive(Debug, thiserror::Error)]
enum SubError<'a> {
    #[error("variant: {0}")]
    Variant(&'a str),
}

This gives the following compilation error:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
 --> src/main.rs:5:17
  |
5 | #[derive(Debug, thiserror::Error)]
  |                 ^^^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 6:12...
 --> src/main.rs:6:12
  |
6 | enum Error<'a> {
  |            ^^
note: ...so that the types are compatible
 --> src/main.rs:5:17
  |
5 | #[derive(Debug, thiserror::Error)]
  |                 ^^^^^^^^^^^^^^^^
  = note: expected  `&Error<'_>`
             found  `&Error<'a>`
  = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `SubError<'_>` will meet its required lifetime bounds
 --> src/main.rs:5:17
  |
5 | #[derive(Debug, thiserror::Error)]
  |                 ^^^^^^^^^^^^^^^^

error: aborting due to previous error

Any ideas as to how this could be solved?

Thanks for your work on anyhow and thiserror; IMHO they are the best the Rust ecosystem has to offer in terms of error handling :)

@dtolnay
Copy link
Owner

dtolnay commented Mar 21, 2020

Hi @arzg, thanks for the report. I released 1.0.12 with a better error message for this case. This doesn't compile because Error::source always needs an inner error that is 'static, and an arbitrary lifetime 'a may not be long enough. You're free to still handwrite a From impl or use some other derive(From) macro to generate it, it just means the inner SubError won't be wired up as the source of the outer Error and thus a derive(Error) isn't the right macro to generate that From impl.

impl<'a> From<SubError<'a>> for Error<'a> {
    fn from(sub: SubError<'a>) -> Error<'a> {
        Error::SubError(sub)
    }
}

@lunacookies
Copy link
Author

Thanks for the quick response and detail. I think what I’ll end up doing is allocate, since performance isn’t much of a concern in this scenario.

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

Successfully merging a pull request may close this issue.

2 participants