diff --git a/src/expressions/block-expr.md b/src/expressions/block-expr.md index a68b27e56..2d660a062 100644 --- a/src/expressions/block-expr.md +++ b/src/expressions/block-expr.md @@ -117,6 +117,30 @@ loop { } ``` +### Auto traits and `async` blocks + +Auto trait inference for `async` blocks follow the same [rules as closures] except that values that are live across an `await` expression are also considered. +Live values are variables or temporaries that are defined before an `await` expression and potentially used afterwards. +As an example, see below: +```rust +# struct Bar; +# async fn foo() {} +async { + let x = Bar; + foo().await; + drop(x); +} +# ; +``` +Here the resulting future will be `Send` if `Bar` is send, since `x` is defined before the await and used afterwards. +If the `drop(x)` line were removed, then `x` would not be considered in auto trait inference because it is not live across the await point. + +Note that for values of types that implement `Drop`, there is an implicit use of the value at the end of its lifetime in order to run the destructor. + +Besides named variables, temporary values also affect auto trait inference. +For example in `foo(&bar, baz.await)`, the value `&bar` is considered live across the `await` point. +This is also true of the scrutinee of the match expression, since [the scrutinee is live for the entire match block][temporary-scopes]. + ## `unsafe` blocks > **Syntax**\ @@ -189,3 +213,5 @@ fn is_unix_platform() -> bool { [tuple expressions]: tuple-expr.md [unsafe operations]: ../unsafety.md [value expressions]: ../expressions.md#place-expressions-and-value-expressions +[rules as closures]: ../special-types-and-traits.md#auto-traits +[temporary-scopes]: ../destructors.md#temporary-scopes