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

async/await errors should not discuss "yield statements" #51751

Closed
jonathandturner opened this issue Jun 24, 2018 · 10 comments
Closed

async/await errors should not discuss "yield statements" #51751

jonathandturner opened this issue Jun 24, 2018 · 10 comments

Comments

@jonathandturner
Copy link
Contributor

@jonathandturner jonathandturner commented Jun 24, 2018

Awesome to see async/await starting to light up. I poked around and hit a snag putting together a naive little example. Clearly, this example is probably missing a bit more to get it running, but I just wanted to point the error here doesn't quite help:

#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)]

async fn inc(limit: i64) -> i64 {
    limit + 1
}

fn main() {
    let result = inc(10000);
    let finished = await!(result);
}

For the above, you get:

error[E0627]: yield statement outside of generator literal
  --> src/main.rs:22:20
   |
22 |     let finished = await!(result);
   |                    ^^^^^^^^^^^^^^
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

Which immediately makes you wonder "what yield statement?" I suspect one of the first things people will want to try is awaiting an async function, so we might want to gently point them in the right direction.

cc @estebank @cramertj

@cramertj
Copy link
Member

@cramertj cramertj commented Jun 24, 2018

@jonathandturner Ugh-- thanks for pointing this out! This is an annoying result of the fact that await is currently implemented as a plain-old macro rather than something that hooks into the compiler. Error messages should be much better when await is built-in.

cc @eddyb

@eddyb
Copy link
Member

@eddyb eddyb commented Jun 24, 2018

Closely related to #51719.

@brandonros
Copy link

@brandonros brandonros commented Jul 16, 2018

@jonathandturner What ended up being the working code?

@eddyb
Copy link
Member

@eddyb eddyb commented Jul 17, 2018

@brandonros You need to keep await! only in async fns. To actually execute async fns you want the futures crate (possibly futures-preview, not sure), or, more likely, tokio's event loop.
cc @alexcrichton

@brandonros
Copy link

@brandonros brandonros commented Jul 20, 2018

@eddyb I apologize for the extreme lack of knowledge on the topic as I am still a beginner, but I am curious and excited to give Rust a shot once I understand how to use async/await. I am struggling to find any kind of clear example on the Internet (probably because all of this is still so fresh)

Are you saying it is not possible to call await! in main? Is it possible to make main async?

Regarding the futures create, I was under the impression all of the necessary moving pieces for futures/async/await were being brought in to the Rust compiler + standard library so that no external crates would be required.

Can somebody post a full example of what a simple "Hello world" level async/await/futures function would look like (including its invocation from main?)

This is the closest I can come up with what seems it might be in the right direction is

#![feature(async_await, await_macro, futures_api)]

use std::task::Executor;

async fn inc(limit: i64) -> i64 {
    limit + 1
}

async fn run() {
  let result = await!(inc(10000));

  println!("{}", result);
}

fn main() {
  Executor::spawn_obj(&self, run);
}

but this does not compile for many obvious reasons. I feel there isn't any documentation out there that shows how to piece together the new async/await language features with the new std::future library. I think a working example of the pasted above code would be pretty big for the "beginner" community trying to get on board with Rust and not be fragmented between the many different ways to do async code that currently exist (and are most likely outdated/going to get phased out it sounds like with these new RFCs)

@eddyb
Copy link
Member

@eddyb eddyb commented Jul 20, 2018

@brandonros I expect any practical usecase would still involve a tokio dependency (which would implement the executor & waker, for integrating async I/O and other async functionality).
This is a bit offtopic though, I'm guessing you also asked on reddit? That's a better discussion place.

@nikomatsakis nikomatsakis changed the title async/await error message could be better async/await errors should not discuss "yield statements" Feb 22, 2019
@gilescope
Copy link
Contributor

@gilescope gilescope commented Mar 3, 2019

Would some wording like this work:
"yield statement outside of generator literal (Maybe async called from a non-async context?)"

@gilescope
Copy link
Contributor

@gilescope gilescope commented Mar 18, 2019

I can see we have asyncness on the ast. Given that the await! macro disappears I think this is our only hint. Will explore that path.

@cramertj
Copy link
Member

@cramertj cramertj commented Mar 18, 2019

@gilescope IMO fixing this prior to moving to native syntax doesn't really make sense, because at that point I'm assuming we'll have an actual await node in the AST that doesn't become a yield until HIR lowering, which would make fixing this pretty trivial.

@estebank
Copy link
Contributor

@estebank estebank commented Mar 18, 2019

We can create an intrinsic macro (like format) that only calls yield and poisons its span with CompilerDesugaringKind::Await. That way the generic yield error is still emitted except when calling await!().

bors added a commit that referenced this issue May 7, 2019
Implement built-in await syntax

Adds support for .await under the existing async_await feature gate.
Moves macro-like await! syntax to the await_macro feature gate.
Removes support for `await` as a non-keyword under the `async_await`
feature.

This new syntax is not final, but is the consensus solution proposed by the lang team, as explained in https://boats.gitlab.io/blog/post/await-decision/

Fix #51719
Fix #51751
Fix #60016
@bors bors closed this in #60586 May 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

8 participants