Skip to content

Bad help in case of nested closures: consider adding 'move' even if closure is already marked as 'move' #101227

Closed
@JanBeh

Description

@JanBeh

I tried this code:

fn main() {
    let mut vec: Vec<i32> = Vec::new();
    let closure = move || {
        vec.clear();
        let mut iter = vec.iter();
        move || { iter.next() }
    };
}

I expected to see a helpful error message.

Instead, this happened:

error: captured variable cannot escape `FnMut` closure body
 --> src/main.rs:6:9
  |
2 |     let mut vec: Vec<i32> = Vec::new();
  |         ------- variable defined here
3 |     let closure = move || {
  |                         - inferred to be a `FnMut` closure
4 |         vec.clear();
  |         --- variable captured here
5 |         let mut iter = vec.iter();
6 |         move || { iter.next() }
  |         ^^^^^^^^^^^^^^^^^^^^^^^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
  |
  = note: `FnMut` closures only have access to their captured variables while they are executing...
  = note: ...therefore, they cannot allow references to captured variables to escape
help: consider adding 'move' keyword before the nested closure
  |
6 |         move move || { iter.next() }
  |         ++++

Following the compiler's advice and writing move move, this leads to:

error: expected one of `async`, `|`, or `||`, found keyword `move`
 --> src/main.rs:6:14
  |
6 |         move move || { iter.next() }
  |              ^^^^ expected one of `async`, `|`, or `||`

Meta

rustc --version --verbose:

rustc 1.65.0-nightly (02654a084 2022-08-30)
binary: rustc
commit-hash: 02654a0844f5c8d29bac318c3c6c666da3d8543d
commit-date: 2022-08-30
host: x86_64-unknown-freebsd
release: 1.65.0-nightly
LLVM version: 15.0.0

Metadata

Metadata

Assignees

Labels

A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.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