|
8 | 8 | > [_BlockExpression_]
|
9 | 9 | >
|
10 | 10 | > _FunctionQualifiers_ :\
|
11 |
| -> `const`<sup>?</sup> `unsafe`<sup>?</sup> (`extern` _Abi_<sup>?</sup>)<sup>?</sup> |
| 11 | +> _AsyncConstQualifiers_<sup>?</sup> `unsafe`<sup>?</sup> (`extern` _Abi_<sup>?</sup>)<sup>?</sup> |
| 12 | +> |
| 13 | +> _AsyncConstQualifiers_ :\ |
| 14 | +> `async` | `const` |
12 | 15 | >
|
13 | 16 | > _Abi_ :\
|
14 | 17 | > [STRING_LITERAL] | [RAW_STRING_LITERAL]
|
@@ -189,6 +192,104 @@ Exhaustive list of permitted structures in const functions:
|
189 | 192 | the following unsafe operations:
|
190 | 193 | * calls to const unsafe functions
|
191 | 194 |
|
| 195 | +## Async functions |
| 196 | + |
| 197 | +Functions may be qualified as async, and this can also be combined with the |
| 198 | +`unsafe` qualifier: |
| 199 | + |
| 200 | +```rust,edition2018 |
| 201 | +async fn regular_example() { } |
| 202 | +async unsafe fn unsafe_example() { } |
| 203 | +``` |
| 204 | + |
| 205 | +Async functions do no work when called: instead, they |
| 206 | +capture their arguments into a future. When polled, that future will |
| 207 | +execute the function's body. |
| 208 | + |
| 209 | +An async function is roughly equivalent to a function |
| 210 | +that returns [`impl Future`] and with an [`async move` block][async-blocks] as |
| 211 | +its body: |
| 212 | + |
| 213 | +```rust,edition2018 |
| 214 | +// Source |
| 215 | +async fn example(x: &str) -> usize { |
| 216 | + x.len() |
| 217 | +} |
| 218 | +``` |
| 219 | + |
| 220 | +is roughly equivalent to: |
| 221 | + |
| 222 | +```rust,edition2018 |
| 223 | +# use std::future::Future; |
| 224 | +// Desugared |
| 225 | +fn example<'a>(x: &'a str) -> impl Future<Output = usize> + 'a { |
| 226 | + async move { x.len() } |
| 227 | +} |
| 228 | +``` |
| 229 | + |
| 230 | +The actual desugaring is more complex: |
| 231 | + |
| 232 | +- The return type in the desugaring is assumed to capture all lifetime |
| 233 | + parameters from the `async fn` declaration. This can be seen in the |
| 234 | + desugared example above, which explicitly outlives, and hence |
| 235 | + captures, `'a`. |
| 236 | +- The [`async move` block][async-blocks] in the body captures all function |
| 237 | + parameters, including those that are unused or bound to a `_` |
| 238 | + pattern. This ensures that function parameters are dropped in the |
| 239 | + same order as they would be if the function were not async, except |
| 240 | + that the drop occurs when the returned future has been fully |
| 241 | + awaited. |
| 242 | + |
| 243 | +For more information on the effect of async, see [`async` blocks][async-blocks]. |
| 244 | + |
| 245 | +[async-blocks]: ../expressions/block-expr.md#async-blocks |
| 246 | +[`impl Future`]: ../types/impl-trait.md |
| 247 | + |
| 248 | +> **Edition differences**: Async functions are only available beginning with |
| 249 | +> Rust 2018. |
| 250 | +
|
| 251 | +### Combining `async` and `unsafe` |
| 252 | + |
| 253 | +It is legal to declare a function that is both async and unsafe. The |
| 254 | +resulting function is unsafe to call and (like any async function) |
| 255 | +returns a future. This future is just an ordinary future and thus an |
| 256 | +`unsafe` context is not required to "await" it: |
| 257 | + |
| 258 | +```rust,edition2018 |
| 259 | +// Returns a future that, when awaited, dereferences `x`. |
| 260 | +// |
| 261 | +// Soundness condition: `x` must be safe to dereference until |
| 262 | +// the resulting future is complete. |
| 263 | +async unsafe fn unsafe_example(x: *const i32) -> i32 { |
| 264 | + *x |
| 265 | +} |
| 266 | +
|
| 267 | +async fn safe_example() { |
| 268 | + // An `unsafe` block is required to invoke the function initially: |
| 269 | + let p = 22; |
| 270 | + let future = unsafe { unsafe_example(&p) }; |
| 271 | + |
| 272 | + // But no `unsafe` block required here. This will |
| 273 | + // read the value of `p`: |
| 274 | + let q = future.await; |
| 275 | +} |
| 276 | +``` |
| 277 | + |
| 278 | +Note that this behavior is a consequence of the desugaring to a |
| 279 | +function that returns an `impl Future` -- in this case, the function |
| 280 | +we desugar to is an `unsafe` function, but the return value remains |
| 281 | +the same. |
| 282 | + |
| 283 | +Unsafe is used on an async function in precisely the same way that it |
| 284 | +is used on other functions: it indicates that the function imposes |
| 285 | +some additional obligations on its caller to ensure soundness. As in any |
| 286 | +other unsafe function, these conditions may extend beyond the initial |
| 287 | +call itself -- in the snippet above, for example, the `unsafe_example` |
| 288 | +function took a pointer `x` as argument, and then (when awaited) |
| 289 | +dereferenced that pointer. This implies that `x` would have to be |
| 290 | +valid until the future is finished executing, and it is the callers |
| 291 | +responsibility to ensure that. |
| 292 | + |
192 | 293 | ## Attributes on functions
|
193 | 294 |
|
194 | 295 | [Outer attributes][attributes] are allowed on functions. [Inner
|
|
0 commit comments