rust-lang / rust-lang/rust

Closure lifetime error doesn't reference variable when `move` is used

Open
#119,757 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Code
fn foo<'a>(bar: &'a u8) {
    let _bad_closure: Box<dyn FnOnce() + 'static> = Box::new(move || {
        println!("Var: {bar}");
    });
}
Current output
error: lifetime may not live long enough
 --> src/lib.rs:2:23
  |
1 | fn foo<'a>(bar: &'a u8) {
  |        -- lifetime `'a` defined here
2 |     let _bad_closure: Box<dyn FnOnce() + 'static> = Box::new(move || {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

error: could not compile `playground` (lib) due to 1 previous error
Desired output

The usage of 'bar' should be mentioned.

Rationale and extra context

No response

Other cases

Removing the 'move' keyowrd produces a much better error message:

fn foo<'a>(bar: &'a u8) {
    let _bad_closure: Box<dyn FnOnce() + 'static> = Box::new(|| {
        println!("Var: {bar}");
    });
}

produces:

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:2:23
  |
1 | fn foo<'a>(bar: &'a u8) {
  |        -- lifetime `'a` defined here
2 |     let _bad_closure: Box<dyn FnOnce() + 'static> = Box::new(|| {
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

error[E0597]: `bar` does not live long enough
 --> src/lib.rs:3:25
  |
2 |     let _bad_closure: Box<dyn FnOnce() + 'static> = Box::new(|| {
  |                       ---------------------------            -- value captured here
  |                       |
  |                       type annotation requires that `bar` is borrowed for `'static`
3 |         println!("Var: {bar}");
  |                         ^^^ borrowed value does not live long enough
4 |     });
5 | }
  |  - `bar` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (lib) due to 2 previous errors
Rust Version
rustc 1.77.0-nightly (ca663b06c 2024-01-08)
binary: rustc
commit-hash: ca663b06c5492ac2dde5e53cd11579fa8e4d68bd
commit-date: 2024-01-08
host: x86_64-unknown-linux-gnu
release: 1.77.0-nightly
LLVM version: 17.0.6
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

Compile the provided closure example with the stated Rust version, then compare its diagnostics with the non-move variant. Trace the compiler's lifetime and closure-capture diagnostics to determine why bar is omitted when move is used. Done means the move case identifies the captured bar usage without regressing the existing diagnostics.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
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.