From 43cdd4bcf25953cb86bccbd57df98c923e16804e Mon Sep 17 00:00:00 2001 From: Yoshua Wuyts <2467194+yoshuawuyts@users.noreply.github.com> Date: Fri, 1 Jul 2022 13:00:09 +0200 Subject: [PATCH 1/2] Add `IntoFuture::into_future` desugaring --- src/expressions/await-expr.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/expressions/await-expr.md b/src/expressions/await-expr.md index e7fc45d27..84cae07a4 100644 --- a/src/expressions/await-expr.md +++ b/src/expressions/await-expr.md @@ -4,17 +4,20 @@ > _AwaitExpression_ :\ >    [_Expression_] `.` `await` -*Await expressions* suspend the current computation until the given future is ready to produce a value. -The syntax for an await expression is an expression with a type that implements the [Future] trait, called the *future operand*, then the token `.`, and then the `await` keyword. +An `await` expression is a syntactic construct for suspending a computation +provided by an implementation of `std::future::IntoFuture` until the given +future is ready to produce a value. +The syntax for an await expression is an expression with a type that implements the [IntoFuture] trait, called the *future operand*, then the token `.`, and then the `await` keyword. Await expressions are legal only within an [async context], like an [`async fn`] or an [`async` block]. More specifically, an await expression has the following effect. -1. Evaluate the future operand to a [future] `tmp`; -2. Pin `tmp` using [`Pin::new_unchecked`]; -3. This pinned future is then polled by calling the [`Future::poll`] method and passing it the current [task context](#task-context); -3. If the call to `poll` returns [`Poll::Pending`], then the future returns `Poll::Pending`, suspending its state so that, when the surrounding async context is re-polled,execution returns to step 2; -4. Otherwise the call to `poll` must have returned [`Poll::Ready`], in which case the value contained in the [`Poll::Ready`] variant is used as the result of the `await` expression itself. +1. Create a future by calling [`IntoFuture::into_future`] on the future operand. +2. Evaluate the future to a [future] `tmp`; +3. Pin `tmp` using [`Pin::new_unchecked`]; +4. This pinned future is then polled by calling the [`Future::poll`] method and passing it the current [task context](#task-context); +5. If the call to `poll` returns [`Poll::Pending`], then the future returns `Poll::Pending`, suspending its state so that, when the surrounding async context is re-polled,execution returns to step 2; +6. Otherwise the call to `poll` must have returned [`Poll::Ready`], in which case the value contained in the [`Poll::Ready`] variant is used as the result of the `await` expression itself. > **Edition differences**: Await expressions are only available beginning with Rust 2018. @@ -29,7 +32,7 @@ Effectively, an await expression is roughly equivalent to the following non-norm ```rust,ignore -match future_operand { +match operand.into_future() { mut pinned => loop { let mut pin = unsafe { Pin::new_unchecked(&mut pinned) }; match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) { @@ -53,3 +56,5 @@ The variable `current_context` refers to the context taken from the async enviro [`poll::Ready`]: ../../std/task/enum.Poll.html#variant.Ready [async context]: ../expressions/block-expr.md#async-context [future]: ../../std/future/trait.Future.html +[`IntoFuture`]: ../../std/future/trait.IntoFuture.html +[`IntoFuture::into_future`]: ../../std/future/trait.IntoFuture.html#tymethod.into_future From be45f8f36860378109dfa1f6a6beedd39e420a9e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 21 Jul 2022 18:58:23 -0700 Subject: [PATCH 2/2] Fix `IntoFuture` link --- src/expressions/await-expr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expressions/await-expr.md b/src/expressions/await-expr.md index 84cae07a4..b52cda1b9 100644 --- a/src/expressions/await-expr.md +++ b/src/expressions/await-expr.md @@ -7,7 +7,7 @@ An `await` expression is a syntactic construct for suspending a computation provided by an implementation of `std::future::IntoFuture` until the given future is ready to produce a value. -The syntax for an await expression is an expression with a type that implements the [IntoFuture] trait, called the *future operand*, then the token `.`, and then the `await` keyword. +The syntax for an await expression is an expression with a type that implements the [`IntoFuture`] trait, called the *future operand*, then the token `.`, and then the `await` keyword. Await expressions are legal only within an [async context], like an [`async fn`] or an [`async` block]. More specifically, an await expression has the following effect.