Skip to content

Improve error message when moving a captured value out of a closure #72210

@gralpli

Description

@gralpli

I tried this code:

fn main() {
    let foo = String::new();
    
    bar(move || std::mem::forget(foo));
}

fn bar<F: Fn()>(a: F) {
    
}

I got this error:

error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
 --> src/main.rs:4:34
  |
2 |     let foo = String::new();
  |         --- captured outer variable
3 |     
4 |     bar(move || std::mem::forget(foo));
  |                                  ^^^ move occurs because `foo` has type `std::string::String`, which does not implement the `Copy` trait

The error message is because the closure is not FnOnce() – it could be called multiple times. So this is correct.

But I think the error message is confusing, because it says something about moving out of foo. What’s happening instead is that the captured foo is moved out of the closure that needs it to stay there for a second call.

Meta

rustc --version --verbose:

rustc 1.45.0-nightly (a08c47310 2020-05-07)
binary: rustc
commit-hash: a08c47310c7d49cbdc5d7afb38408ba519967ecd
commit-date: 2020-05-07
host: x86_64-unknown-linux-gnu
release: 1.45.0-nightly
LLVM version: 9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions