rust-lang / rust-lang/rust

This "escapes the function body here" error could use more details

Open
#126,739 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
trait Transaction {
    fn delete_task(&mut self, id: i32);

    // Commit and consume the transaction.
    //
    // See https://stackoverflow.com/q/46620790 for why this argument
    // is boxed.
    fn commit(self: Box<Self>);
}

trait Repository {
    fn transaction(&mut self) -> Box<dyn Transaction + '_>;
}

fn with_transaction<F>(store: &mut dyn Repository, callback: F)
where
    F: FnOnce(&mut Box<dyn Transaction>),
{
    let mut txn = store.transaction();
    callback(&mut txn);
    txn.commit();
}

playground link

Current output
Compiling playground v0.0.1 (/playground)
error[E0521]: borrowed data escapes outside of function
  --> src/lib.rs:19:19
   |
15 | fn with_transaction<F>(store: &mut dyn Repository, callback: F)
   |                        -----  - let's call the lifetime of this reference `'1`
   |                        |
   |                        `store` is a reference that is only valid in the function body
...
19 |     let mut txn = store.transaction();
   |                   ^^^^^^^^^^^^^^^^^^^
   |                   |
   |                   `store` escapes the function body here
   |                   argument requires that `'1` must outlive `'static`

For more information about this error, try `rustc --explain E0521`.
error: could not compile `playground` (lib) due to 1 previous error
Desired output

See the next section for the additional information I'd like to see in the error.
I'm not exactly sure how it should be formatted.

Rationale and extra context

I think it would be great if:

  1. the error included details about why the lifetime of txn, a Box<Transaction>, in this case must be 'static. The store.transaction() function has an inferred lifetime, requiring only that it be at least as long as store. It isn't obvious why 'static is required. So, highlighting only line 19 is an incomplete description of the problem.
  2. deleting the callback(&mut txn) on line 20 causes the code to compile. The rustc error should probably highlight this line as the "cause" of the 'static lifetime requirement, and explain why.
  3. since 'static is never mentioned explicitly in the code (the type is spelled as &mut Box<Transaction>), some mention of the &mut Box<Transaction + 'static> type being a root cause of the problem feels appropriate.

In summary, the chain of reasoning between the information currently highlighted by rustc and the actual problem is non-obvious and non-trivial (at least, to a newer rust programmer).

Background thread on the rust forum: https://users.rust-lang.org/t/request-help-with-a-borrow-checker-error-im-lost/113149?u=matta

Other cases

No response

Rust Version
rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7
Anything else?

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the E0521 example from the issue using the linked Rust Playground and rustc 1.79.0, then inspect the diagnostic around store.transaction() and callback(&mut txn). The change is done when the error explains why the callback creates the 'static requirement, connects that requirement to the inferred transaction type, and highlights the relevant cause clearly.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.