You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/expressions/await-expr.md
+2-1
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ An `await` expression is a syntactic construct for suspending a computation
8
8
provided by an implementation of `std::future::IntoFuture` until the given
9
9
future is ready to produce a value.
10
10
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.
11
-
Await expressions are legal only within an [async context], like an [`async fn`] or an[`async` block].
11
+
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or[`async` block].
12
12
13
13
More specifically, an await expression has the following effect.
14
14
@@ -48,6 +48,7 @@ The variable `current_context` refers to the context taken from the async enviro
Copy file name to clipboardExpand all lines: src/expressions/call-expr.md
+7-1
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,13 @@
10
10
A *call expression* calls a function.
11
11
The syntax of a call expression is an expression, called the *function operand*, followed by a parenthesized comma-separated list of expression, called the *argument operands*.
12
12
If the function eventually returns, then the expression completes.
13
-
For [non-function types], the expression `f(...)` uses the method on one of the [`std::ops::Fn`], [`std::ops::FnMut`] or [`std::ops::FnOnce`] traits, which differ in whether they take the type by reference, mutable reference, or take ownership respectively.
13
+
14
+
For [non-function types], the expression `f(...)` uses the method on one of the following traits based on the function operand:
15
+
16
+
-[`Fn`] or [`AsyncFn`] --- shared reference.
17
+
-[`FnMut`] or [`AsyncFnMut`] --- mutable reference.
18
+
-[`FnOnce`] or [`AsyncFnOnce`] --- value.
19
+
14
20
An automatic borrow will be taken if needed.
15
21
The function operand will also be [automatically dereferenced] as required.
> [^cl-async-edition]: The `async` qualifier is not allowed in the 2015 edition.
14
17
15
18
A *closure expression*, also known as a lambda expression or a lambda, defines a [closure type] and evaluates to a value of that type.
16
-
The syntax for a closure expression is an optional `move` keyword, then a pipe-symbol-delimited (`|`) comma-separated list of [patterns], called the *closure parameters* each optionally followed by a `:` and a type, then an optional `->` and type, called the *return type*, and then an expression, called the *closure body operand*.
19
+
The syntax for a closure expression is an optional `async` keyword, an optional `move` keyword, then a pipe-symbol-delimited (`|`) comma-separated list of [patterns], called the *closure parameters* each optionally followed by a `:` and a type, then an optional `->` and type, called the *return type*, and then an expression, called the *closure body operand*.
17
20
The optional type after each pattern is a type annotation for the pattern.
18
21
If there is a return type, the closure body must be a [block].
19
22
@@ -29,10 +32,32 @@ This is often used to ensure that the closure's lifetime is `'static`.
29
32
30
33
## Closure trait implementations
31
34
32
-
Which traits the closure type implement depends on how variables are captured and the types of the captured variables.
35
+
Which traits the closure type implement depends on how variables are captured, the types of the captured variables, and the presence of `async`.
33
36
See the [call traits and coercions] chapter for how and when a closure implements `Fn`, `FnMut`, and `FnOnce`.
34
37
The closure type implements [`Send`] and [`Sync`] if the type of every captured variable also implements the trait.
35
38
39
+
## Async closures
40
+
41
+
Closures marked with the `async` keyword indicate that they are asynchronous in an analogous way to an [async function][items.fn.async].
42
+
43
+
Calling the async closure does not perform any work, but instead evaluates to a value that implements [`Future`] that corresponds to the computation of the body of the closure.
44
+
45
+
```rust
46
+
asyncfntakes_async_callback(f:implAsyncFn(u64)) {
47
+
f(0).await;
48
+
f(1).await;
49
+
}
50
+
51
+
asyncfnexample() {
52
+
takes_async_callback(async|i| {
53
+
core::future::ready(i).await;
54
+
println!("done with {i}.");
55
+
}).await;
56
+
}
57
+
```
58
+
59
+
> **Edition differences**: Async closures are only available beginning with Rust 2018.
60
+
36
61
## Example
37
62
38
63
In this example, we define a function `ten_times` that takes a higher-order function argument, and we then call it with a closure expression as an argument, followed by a closure expression that moves values from its environment.
Copy file name to clipboardExpand all lines: src/types/closure.md
+66-2
Original file line number
Diff line number
Diff line change
@@ -94,6 +94,11 @@ let c = || {
94
94
};
95
95
```
96
96
97
+
### Async input capture
98
+
99
+
r[type.closure.async.input]
100
+
Async closures always capture all input arguments, regardless of whether or not they are used within the body.
101
+
97
102
## Capture Precision
98
103
99
104
r[type.closure.capture.precision.capture-path]
@@ -491,7 +496,7 @@ r[type.closure.call.fn]
491
496
492
497
r[type.closure.non-capturing]
493
498
*Non-capturing closures* are closures that don't capture anything from their
494
-
environment. They can be coerced to function pointers (e.g., `fn()`)
499
+
environment. Non-async, non-capturing closures can be coerced to function pointers (e.g., `fn()`)
495
500
with the matching signature.
496
501
497
502
```rust
@@ -504,7 +509,66 @@ let bo: Binop = add;
504
509
x=bo(5,7);
505
510
```
506
511
507
-
## Other traits
512
+
### Async closure traits
513
+
514
+
r[type.closure.async.traits]
515
+
516
+
r[type.closure.async.traits.fn-family]
517
+
Async closures have a further restriction of whether or not they implement [`FnMut`] or [`Fn`].
518
+
519
+
The [`Future`] returned by the async closure has similar capturing characteristics as a closure. It captures place expressions from the async closure based on how they are used. The async closure is said to be *lending* to its [`Future`] if it has either of the following properties:
520
+
521
+
- The `Future` includes a mutable capture.
522
+
- The async closure captures by value, except when the value is accessed with a dereference projection.
523
+
524
+
If the async closure is lending to its `Future`, then [`FnMut`] and [`Fn`] are *not* implemented. [`FnOnce`] is always implemented.
525
+
526
+
> **Example**: The first clause for a mutable capture can be illustrated with the following:
Async closures implement [`AsyncFn`], [`AsyncFnMut`], and [`AsyncFnOnce`] in an analogous way as regular closures implement [`Fn`], [`FnMut`], and [`FnOnce`]; that is, depending on the use of the captured variables in its body.
0 commit comments