|
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]
|
@@ -227,6 +230,104 @@ Exhaustive list of permitted structures in const functions:
|
227 | 230 | the following unsafe operations:
|
228 | 231 | * calls to const unsafe functions
|
229 | 232 |
|
| 233 | +## Async functions |
| 234 | + |
| 235 | +Functions may be qualified as async, and this can also be combined with the |
| 236 | +`unsafe` qualifier: |
| 237 | + |
| 238 | +```rust,edition2018 |
| 239 | +async fn regular_example() { } |
| 240 | +async unsafe fn unsafe_example() { } |
| 241 | +``` |
| 242 | + |
| 243 | +Async functions do no work when called: instead, they |
| 244 | +capture their arguments into a future. When polled, that future will |
| 245 | +execute the function's body. |
| 246 | + |
| 247 | +An async function is roughly equivalent to a function |
| 248 | +that returns [`impl Future`] and with an [`async move` block][async-blocks] as |
| 249 | +its body: |
| 250 | + |
| 251 | +```rust,edition2018 |
| 252 | +// Source |
| 253 | +async fn example(x: &str) -> usize { |
| 254 | + x.len() |
| 255 | +} |
| 256 | +``` |
| 257 | + |
| 258 | +is roughly equivalent to: |
| 259 | + |
| 260 | +```rust,edition2018 |
| 261 | +# use std::future::Future; |
| 262 | +// Desugared |
| 263 | +fn example<'a>(x: &'a str) -> impl Future<Output = usize> + 'a { |
| 264 | + async move { x.len() } |
| 265 | +} |
| 266 | +``` |
| 267 | + |
| 268 | +The actual desugaring is more complex: |
| 269 | + |
| 270 | +- The return type in the desugaring is assumed to capture all lifetime |
| 271 | + parameters from the `async fn` declaration. This can be seen in the |
| 272 | + desugared example above, which explicitly outlives, and hence |
| 273 | + captures, `'a`. |
| 274 | +- The [`async move` block][async-blocks] in the body captures all function |
| 275 | + parameters, including those that are unused or bound to a `_` |
| 276 | + pattern. This ensures that function parameters are dropped in the |
| 277 | + same order as they would be if the function were not async, except |
| 278 | + that the drop occurs when the returned future has been fully |
| 279 | + awaited. |
| 280 | + |
| 281 | +For more information on the effect of async, see [`async` blocks][async-blocks]. |
| 282 | + |
| 283 | +[async-blocks]: ../expressions/block-expr.md#async-blocks |
| 284 | +[`impl Future`]: ../types/impl-trait.md |
| 285 | + |
| 286 | +> **Edition differences**: Async functions are only available beginning with |
| 287 | +> Rust 2018. |
| 288 | +
|
| 289 | +### Combining `async` and `unsafe` |
| 290 | + |
| 291 | +It is legal to declare a function that is both async and unsafe. The |
| 292 | +resulting function is unsafe to call and (like any async function) |
| 293 | +returns a future. This future is just an ordinary future and thus an |
| 294 | +`unsafe` context is not required to "await" it: |
| 295 | + |
| 296 | +```rust,edition2018 |
| 297 | +// Returns a future that, when awaited, dereferences `x`. |
| 298 | +// |
| 299 | +// Soundness condition: `x` must be safe to dereference until |
| 300 | +// the resulting future is complete. |
| 301 | +async unsafe fn unsafe_example(x: *const i32) -> i32 { |
| 302 | + *x |
| 303 | +} |
| 304 | +
|
| 305 | +async fn safe_example() { |
| 306 | + // An `unsafe` block is required to invoke the function initially: |
| 307 | + let p = 22; |
| 308 | + let future = unsafe { unsafe_example(&p) }; |
| 309 | + |
| 310 | + // But no `unsafe` block required here. This will |
| 311 | + // read the value of `p`: |
| 312 | + let q = future.await; |
| 313 | +} |
| 314 | +``` |
| 315 | + |
| 316 | +Note that this behavior is a consequence of the desugaring to a |
| 317 | +function that returns an `impl Future` -- in this case, the function |
| 318 | +we desugar to is an `unsafe` function, but the return value remains |
| 319 | +the same. |
| 320 | + |
| 321 | +Unsafe is used on an async function in precisely the same way that it |
| 322 | +is used on other functions: it indicates that the function imposes |
| 323 | +some additional obligations on its caller to ensure soundness. As in any |
| 324 | +other unsafe function, these conditions may extend beyond the initial |
| 325 | +call itself -- in the snippet above, for example, the `unsafe_example` |
| 326 | +function took a pointer `x` as argument, and then (when awaited) |
| 327 | +dereferenced that pointer. This implies that `x` would have to be |
| 328 | +valid until the future is finished executing, and it is the callers |
| 329 | +responsibility to ensure that. |
| 330 | + |
230 | 331 | ## Attributes on functions
|
231 | 332 |
|
232 | 333 | [Outer attributes][attributes] are allowed on functions. [Inner
|
|
0 commit comments