Skip to content

Lifetime error message is backwards: lifetime of reference outlives lifetime of borrowed content #44470

Closed
@bluss

Description

@bluss

I think this diagnostic can be improved.
When compiling this code:

fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &'b str {
    a
}

We get this diagnostic:

error[E0312]: lifetime of reference outlives lifetime of borrowed content...
 --> src/main.rs:4:5
  |
4 |     a
  |     ^
  |
note: ...the reference is valid for the lifetime 'b as defined on the function body at 3:1...
 --> src/main.rs:3:1
  |
3 | / fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &'b str {
4 | |     a
5 | | }
  | |_^
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 3:1
 --> src/main.rs:3:1
  |
3 | / fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &'b str {
4 | |     a
5 | | }
  | |_^

The Problematic Code

The code is trying to return a reference with lifetime 'a where 'b should be, and the two are not compatible in any direction.

Equivalently, either or:

  • The user is supplying a reference that is not valid long enough to match the signature
  • The user is supplying a signature that is not matching the reference that is being returned

Problems With the Diagnostic

The first line is: lifetime of reference outlives lifetime of borrowed content...

  1. The error doesn't mention "return type", it probably should to be clear

  2. The error is subjectively “backwards”, it feels a bit alien. It's telling us that the return type specifies a lifetime that is longer than the borrow that was passed.

    • The forwards direction is: borrowed content does not live long enough for the lifetime of the reference (in the return type).
  3. reference” in this sentence refers to the reference in the return type (&'b str); but the user will often think in concrete terms. If you say reference, they will think of a, the variable that holds a reference

    • Especially the note “the reference is valid for the lifetime 'b” sounds very concrete, and it's confusing that this is not referring to any variable at all, still just the return type.

Proposed Solution

Change error message to something like:

borrowed content does not live long enough for reference in the return type of function foo

or

borrowed content does not live long enough to be returned from function foo

This is inspired by a discussion in #rust-beginners on irc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.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