This "escapes the function body here" error could use more details
Nobody has claimed this yet.
- 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();
}
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:
- the error included details about why the lifetime of
txn, aBox<Transaction>, in this case must be 'static. Thestore.transaction()function has an inferred lifetime, requiring only that it be at least as long asstore. It isn't obvious why 'static is required. So, highlighting only line 19 is an incomplete description of the problem. - 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. - 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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