diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index a0e5f3a6f..b1ba24137 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -67,6 +67,7 @@
- [If and if let expressions](expressions/if-expr.md)
- [Match expressions](expressions/match-expr.md)
- [Return expressions](expressions/return-expr.md)
+ - [Await expressions](expressions/await-expr.md)
- [Patterns](patterns.md)
diff --git a/src/expressions.md b/src/expressions.md
index c211fa933..75ea56478 100644
--- a/src/expressions.md
+++ b/src/expressions.md
@@ -13,6 +13,7 @@
> | [_OperatorExpression_]\
> | [_GroupedExpression_]\
> | [_ArrayExpression_]\
+> | [_AwaitExpression_]\
> | [_IndexExpression_]\
> | [_TupleExpression_]\
> | [_TupleIndexingExpression_]\
@@ -33,6 +34,7 @@
> [_OuterAttribute_]\*[†](#expression-attributes)\
> (\
> [_BlockExpression_]\
+> | [_AsyncBlockExpression_]\
> | [_UnsafeBlockExpression_]\
> | [_LoopExpression_]\
> | [_IfExpression_]\
@@ -324,6 +326,8 @@ They are never allowed before:
[_ArithmeticOrLogicalExpression_]: expressions/operator-expr.md#arithmetic-and-logical-binary-operators
[_ArrayExpression_]: expressions/array-expr.md
+[_AsyncBlockExpression_]: expressions/block-expr.md#async-blocks
+[_AwaitExpression_]: expressions/await-expr.md
[_AssignmentExpression_]: expressions/operator-expr.md#assignment-expressions
[_BlockExpression_]: expressions/block-expr.md
[_BreakExpression_]: expressions/loop-expr.md#break-expressions
diff --git a/src/expressions/await-expr.md b/src/expressions/await-expr.md
new file mode 100644
index 000000000..95037d73d
--- /dev/null
+++ b/src/expressions/await-expr.md
@@ -0,0 +1,68 @@
+# 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 `.await` expression has the following effect.
+
+1. Evaluate `` 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.
+
+[`async fn`]: ../items/functions.md#async-functions
+[`async` block]: block-expr.md#async-blocks
+[future]: ../../std/future/trait.Future.html
+[_Expression_]: ../expressions.md
+[`Future::poll`]: ../../std/future/trait.Future.html#tymethod.poll
+[`Context`]: ../../std/task/struct.Context.html
+[`Pin::new_unchecked`]: ../../std/pin/struct.Pin.html#method.new_unchecked
+[`Poll::Pending`]: ../../std/task/enum.Poll.html#variant.Pending
+[`Poll::Ready`]: ../../std/task/enum.Poll.html#variant.Ready
+
+> **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.
+
+[`Context`]: ../../std/task/struct.Context.html
+[async context]: ../expressions/block-expr.md#async-context
+
+## Approximate desugaring
+
+Effectively, an `.await` expression is roughly
+equivalent to the following (this desugaring is not normative):
+
+```rust,ignore
+let future = /* */;
+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.
diff --git a/src/expressions/block-expr.md b/src/expressions/block-expr.md
index cfc7b0b08..9362ab9a7 100644
--- a/src/expressions/block-expr.md
+++ b/src/expressions/block-expr.md
@@ -80,6 +80,74 @@ fn move_by_block_expression() {
}
```
+## `async` blocks
+
+> **Syntax**\
+> _AsyncBlockExpression_ :\
+> `async` `move`? _BlockExpression_
+
+An *async block* is a variant of a block expression which evaluates to
+a *future*. The final expression of the block, if present, determines
+the result value of the future.
+
+Executing an async block is similar to executing a closure expression:
+its immediate effect is to produce and return an anonymous type.
+Whereas closures return a type that implements one or more of the
+[`std::ops::Fn`] traits, however, the type returned for an async block
+implements the [`std::future::Future`] trait. The actual data format for
+this type is unspecified.
+
+> **Note:** The future type that rustc generates is roughly equivalent
+> to an enum with one variant per `await` point, where each variant
+> stores the data needed to resume from its corresponding point.
+
+> **Edition differences**: Async blocks are only available beginning with Rust 2018.
+
+[`std::ops::Fn`]: ../../std/ops/trait.Fn.html
+[`std::future::Future`]: ../../std/future/trait.Future.html
+
+### Capture modes
+
+Async blocks capture variables from their environment using the same
+[capture modes] as closures. Like closures, when written `async {
+.. }` the capture mode for each variable will be inferred from the
+content of the block. `async move { .. }` blocks however will move all
+referenced variables into the resulting future.
+
+[capture modes]: ../types/closure.md#capture-modes
+[shared references]: ../types/pointer.md#shared-references-
+[mutable reference]: ../types/pointer.md#mutables-references-
+
+### Async context
+
+Because async blocks construct a future, they define an **async
+context** which can in turn contain [`await` expressions]. Async
+contexts are established by async blocks as well as the bodies of
+async functions, whose semantics are defined in terms of async blocks.
+
+[`await` expressions]: await-expr.md
+
+### Control-flow operators
+
+Async blocks act like a function boundary, much like
+closures. Therefore, the `?` operator and `return` expressions both
+affect the output of the future, not the enclosing function or other
+context. That is, `return ` from within a closure will return
+the result of `` as the output of the future. Similarly, if
+`?` propagates an error, that error is propagated as the result
+of the future.
+
+Finally, the `break` and `continue` keywords cannot be used to branch
+out from an async block. Therefore the following is illegal:
+
+```rust,edition2018,compile_fail
+loop {
+ async move {
+ break; // This would break out of the loop.
+ }
+}
+```
+
## `unsafe` blocks
> **Syntax**\
diff --git a/src/items/functions.md b/src/items/functions.md
index bae5b8eff..44236c273 100644
--- a/src/items/functions.md
+++ b/src/items/functions.md
@@ -8,7 +8,10 @@
> [_BlockExpression_]
>
> _FunctionQualifiers_ :\
-> `const`? `unsafe`? (`extern` _Abi_?)?
+> _AsyncConstQualifiers_? `unsafe`? (`extern` _Abi_?)?
+>
+> _AsyncConstQualifiers_ :\
+> `async` | `const`
>
> _Abi_ :\
> [STRING_LITERAL] | [RAW_STRING_LITERAL]
@@ -189,6 +192,104 @@ Exhaustive list of permitted structures in const functions:
the following unsafe operations:
* calls to const unsafe functions
+## Async functions
+
+Functions may be qualified as async, and this can also be combined with the
+`unsafe` qualifier:
+
+```rust,edition2018
+async fn regular_example() { }
+async unsafe fn unsafe_example() { }
+```
+
+Async functions do no work when called: instead, they
+capture their arguments into a future. When polled, that future will
+execute the function's body.
+
+An async function is roughly equivalent to a function
+that returns [`impl Future`] and with an [`async move` block][async-blocks] as
+its body:
+
+```rust,edition2018
+// Source
+async fn example(x: &str) -> usize {
+ x.len()
+}
+```
+
+is roughly equivalent to:
+
+```rust,edition2018
+# use std::future::Future;
+// Desugared
+fn example<'a>(x: &'a str) -> impl Future