Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
JanBeh opened this issue Aug 31, 2022 · 0 comments · Fixed by #101285
Assignees
Labels
A-closures Area: Closures (`|…| { … }`) A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@JanBeh
Copy link
Contributor

JanBeh commented Aug 31, 2022

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
@JanBeh JanBeh added the C-bug Category: This is a bug. label Aug 31, 2022
@TaKO8Ki TaKO8Ki added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 31, 2022
@TaKO8Ki TaKO8Ki self-assigned this Aug 31, 2022
@estebank estebank added A-closures Area: Closures (`|…| { … }`) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Aug 31, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Sep 1, 2022
…-when-closure-is-already-marked-as-move, r=oli-obk

Do not suggest adding `move` to closure when `move` is already used

Fixes rust-lang#101227
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Sep 1, 2022
…-when-closure-is-already-marked-as-move, r=oli-obk

Do not suggest adding `move` to closure when `move` is already used

Fixes rust-lang#101227
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Sep 1, 2022
…-when-closure-is-already-marked-as-move, r=oli-obk

Do not suggest adding `move` to closure when `move` is already used

Fixes rust-lang#101227
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants