Await expressions
Syntax
AwaitExpression :
Expression.
await
Await expressions are legal only within an async context, like an
async fn
or an async
block. They operate on a future. Their effect
is to suspend the current computation until the given future is ready
to produce a value.
More specifically, an <expr>.await
expression has the following effect.
- Evaluate
<expr>
to a futuretmp
; - Pin
tmp
usingPin::new_unchecked
; - This pinned future is then polled by calling the
Future::poll
method and passing it the current task context; - If the call to
poll
returnsPoll::Pending
, then the future returnsPoll::Pending
, suspending its state so that, when the surrounding async context is re-polled, execution returns to step 2; - Otherwise the call to
poll
must have returnedPoll::Ready
, in which case the value contained in thePoll::Ready
variant is used as the result of theawait
expression itself.
Edition differences: Await expressions are only available beginning with Rust 2018.
Task context
The task context refers to the Context
which was supplied to the
current async context when the async context itself was
polled. Because await
expressions are only legal in an async
context, there must be some task context available.
Approximate desugaring
Effectively, an <expr>.await
expression is roughly
equivalent to the following (this desugaring is not normative):
let future = /* <expr> */;
loop {
let mut pin = unsafe { Pin::new_unchecked(&mut future) };
match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) {
Poll::Ready(r) => break r,
Poll::Pending => yield Poll::Pending,
}
}
where the yield
pseudo-code returns Poll::Pending
and, when
re-invoked, resumes execution from that point. The variable
current_context
refers to the context taken from the async
environment.