Skip to content

Confusing diagnostic when the error value converted by ? fails to satisfy a 'static bound #136902

Open
@Zalathar

Description

@Zalathar

Universal error types like anyhow::Error typically require that the wrapped error be 'static, to avoid lifetime annotations in the overwhelmingly common case.

Some libraries, such as zerocopy and nom, routinely return non-static error values that borrow from an input value. If a 'static error is needed, the expectation is that the user will convert the error value to something more suitable, via map_err or similar.

(While a static input would result in an error value that satisfies 'static, that is usually impractical.)

When using the ? operator to try to convert one of those non-static errors to a universal error that requires 'static, without an intermediate conversion to something that is static, the resulting lifetime error tends to be technically-correct but very confusing:

use anyhow; // 1.0.95
use zerocopy; // 0.8.16

use zerocopy::TryFromBytes;

pub fn main() -> anyhow::Result<()> {
    let input: Vec<u8> = vec![];
    let _ = u64::try_read_from_bytes(&input)?;
    Ok(())
}

(Playground link)

Actual error

(Stable Rust 1.84.1, via playground)

error[E0597]: `input` does not live long enough
  --> src/main.rs:8:38
   |
7  |     let input: Vec<u8> = vec![];
   |         ----- binding `input` declared here
8  |     let _ = u64::try_read_from_bytes(&input)?;
   |             -------------------------^^^^^^-
   |             |                        |
   |             |                        borrowed value does not live long enough
   |             argument requires that `input` is borrowed for `'static`
9  |     Ok(())
10 | }
   | - `input` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to 1 previous error

The compiler's implied reasoning here is:

  • To satisfy conversion to anyhow::Error, the error value must be 'static.
  • The error value is not 'static, so there is a problem.
  • The error value would be static, if only input were static.
  • Therefore, the problem is that input doesn't live long enough.

This is confusing, because making input live for 'static is unlikely to be a reasonable solution.

Expected error

The compiler should point out that the original error type is not 'static, which is required by the conversion, and suggest using map_err to convert it into something that is static.

Metadata

Metadata

Assignees

Labels

A-borrow-checkerArea: The borrow checkerA-diagnosticsArea: Messages for errors, warnings, and lintsA-trait-systemArea: Trait systemD-confusingDiagnostics: Confusing error or lint that should be reworked.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions