Skip to content

Error message for closure with async block needs improvement #68119

Description

@tmandry

Playground

fn do_stuff(foo: Option<Foo>) {
    require_fn_trait(|| async {
        if foo.map_or(false, |f| f.foo()) {
            panic!("foo");
        }
        //ready(())
    })
}

gives

error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
  --> src/lib.rs:14:31
   |
13 |   fn do_stuff(foo: Option<Foo>) {
   |               --- captured outer variable
14 |       require_fn_trait(|| async {
   |  _______________________________^
15 | |         if foo.map_or(false, |f| f.foo()) {
   | |            ---
   | |            |
   | |            move occurs because `foo` has type `std::option::Option<Foo>`, which does not implement the `Copy` trait
   | |            move occurs due to use in generator
16 | |             panic!("foo");
17 | |         }
18 | |         //ready(())
19 | |     })
   | |_____^ move out of `foo` occurs here
   |
help: consider borrowing the `Option`'s content
   |
14 |     require_fn_trait(|| async {
15 |         if foo.map_or(false, |f| f.foo()) {
16 |             panic!("foo");
17 |         }
18 |         //ready(())
19 |     }.as_ref())
   |

Note move occurs due to use in generator. Also, the code is being output twice, for some reason.

If you take this out of the async context by removing async and uncommenting ready(()), you get a better suggestion to use as_ref() and an all-around cleaner error message:

error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
  --> src/lib.rs:15:12
   |
13 | fn do_stuff(foo: Option<Foo>) {
   |             --- captured outer variable
14 |     require_fn_trait(|| {
15 |         if foo.map_or(false, |f| f.foo()) {
   |            ^^^
   |            |
   |            move occurs because `foo` has type `std::option::Option<Foo>`, which does not implement the `Copy` trait
   |            help: consider borrowing the `Option`'s content: `foo.as_ref()`

Thanks to @JakeEhrlich for originally reporting this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.P-mediumMedium priorityT-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