Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Suggest async {} for async || {} #76011

Closed
jyn514 opened this issue Aug 28, 2020 · 4 comments · Fixed by #76580
Closed

Suggest async {} for async || {} #76011

jyn514 opened this issue Aug 28, 2020 · 4 comments · Fixed by #76580
Labels
A-async-await Area: Async & Await A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jyn514
Copy link
Member

jyn514 commented Aug 28, 2020

This code (playground):

fn main() {
    let my_future = async || {
        1
    };
}

prints out

error[E0658]: async closures are unstable
 --> src/main.rs:2:21
  |
2 |     let my_future = async || {
  |                     ^^^^^
  |
  = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information

error: aborting due to previous error

This is pretty unhelpful for beginners - normally this happens when they try to use await in a closure, which tells them they need async:

error[E0728]: `await` is only allowed inside `async` functions and blocks
 --> src/main.rs:3:9
  |
2 |     let my_future = || {
  |                     -- this is not `async`
3 |         1.await
  |         ^^^^^^^ only allowed inside `async` functions and blocks

But when they do they get an error about async being unstable, which they have no idea how to solve. The fix is to remove the pipe symbols:

async { }

However, this requires knowledge that async blocks desugar internally into closures, which is not at all clear from the syntax. It would be better for the compiler to suggest it:

error[E0658]: async closures are unstable
 --> src/main.rs:2:21
  |
2 |     let my_future = async || {
  |                     ^^^^^^^^^^ help: to use an async block, remove the `||`: `async {`
  |
  = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
@jyn514 jyn514 added A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. A-async-await Area: Async & Await T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 28, 2020
@tmandry tmandry added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Sep 1, 2020
@rokob
Copy link
Contributor

rokob commented Sep 10, 2020

Hey, I saw this and it looked like it might be easy so I took a shot with #76580. I haven't fixed the tests yet because I wasn't sure if this approach is reasonable or not. You end up with

error[E0658]: async closures are unstable
 --> src/main.rs:2:21
  |
2 |     let my_future = async || {
  |                     ^^^^^
  |
  = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
  = help: to use an async block, remove the `||`: `async

error: aborting due to previous error

Re-ordering the note and help, or adding a nested span on async || to put the help would be considerably more involved.

@taiki-e
Copy link
Member

taiki-e commented Nov 19, 2020

Given the current async || is equivalent to || async {}, it may be preferable to suggest || async {} instead of async {}.

@jyn514
Copy link
Member Author

jyn514 commented Nov 19, 2020

@taiki-e the point of this is that the user didn't mean || async {} though. If you add || then you can no longer await it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=083f8dbc81f44245734ff5c7a95e1c69

For context, the original code was something like https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2f095b1aa4d8d3290b2ab41bed482469, where the user tried to use await outside of an async function.

@taiki-e
Copy link
Member

taiki-e commented Nov 19, 2020

@jyn514 Thanks for clarifying. What suggestion is preferable seems to depend on the expected return type.
Perhaps it is preferable to have both notes?

   = help: to use an async block, remove the `||`: `async {`
   = help: to use a closure that returns a future, use `|| async {`

bors added a commit to rust-lang-ci/rust that referenced this issue Jan 12, 2021
Suggest async {} for async || {}

Fixes rust-lang#76011

This adds support for adding help diagnostics to the feature gating checks and
then uses it for the async_closure gate to add the extra bit of help
information as described in the issue.
@bors bors closed this as completed in 5b475a4 Jan 12, 2021
@tmandry tmandry moved this to Done in wg-async work Dec 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants