Skip to content

Commit 629f9b6

Browse files
committed
Describe async closures
1 parent 48a5088 commit 629f9b6

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

posts/2025-02-20-Rust-1.85.0.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,41 @@ Note that automatic fixes via `cargo fix` are very conservative to avoid ever ch
7070

7171
### `async` closures
7272

73-
**🚧 TODO 🚧**
73+
Rust now supports asynchronous closures like `async || {}` which return futures when called. This works like an `async fn` which can also capture values from the local environment, just like the difference between regular closures and functions. This also comes with 3 analogous traits in the standard library prelude: `AsyncFn`, `AsyncFnMut`, and `AsyncFnOnce`.
7474

75-
- [Stabilize async closures](https://github.com/rust-lang/rust/pull/132706)
76-
See [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) for more details.
75+
In some cases, you could already approximate this with a regular closure and an asynchronous block, like `|| async {}`. However, the future returned by such an inner block is not able to borrow from the closure captures, but this does work with `async` closures:
76+
77+
```rust
78+
let mut vec: Vec<String> = vec![];
79+
80+
let closure = async || {
81+
vec.push(ready(String::from("")).await);
82+
};
83+
```
84+
85+
It also has not been possible to properly express higher-ranked function signatures with the `Fn` traits returning a `Future`, but you can write this with the `AsyncFn` traits:
86+
87+
```rust
88+
use core::future::Future;
89+
async fn f<Fut>(_: impl for<'a> Fn(&'a u8) -> Fut)
90+
where
91+
Fut: Future<Output = ()>,
92+
{ todo!() }
93+
94+
async fn f2(_: impl for<'a> AsyncFn(&'a u8))
95+
{ todo!() }
96+
97+
async fn main() {
98+
async fn g(_: &u8) { todo!() }
99+
f(g).await;
100+
//~^ ERROR mismatched types
101+
//~| ERROR one type is more general than the other
102+
103+
f2(g).await; // ok!
104+
}
105+
```
106+
107+
So `async` closures provide first-class solutions to both of these problems! See [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) and the [stabilization report](https://github.com/rust-lang/rust/pull/132706) for more details.
77108

78109
### Hiding trait implementations from diagnostics
79110

0 commit comments

Comments
 (0)