Skip to content

Commit 29582aa

Browse files
More clarifications
1 parent d2446cb commit 29582aa

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

text/3668-async-closure.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ takes_async_closure(async |i| {
125125
});
126126
```
127127

128-
We recommend using `async Fn` and `async ||` for async closures. This is more flexible than a closure returning a future for the reasons described elsewhere in this RFC.
128+
We recommend using `async Fn()`/`async FnMut()`/`async FnOnce()` and `async ||` for async closures. This is more flexible than a closure returning a future for the reasons described elsewhere in this RFC.
129129

130130
Async closures act similarly to closures, and can have parts of their their signatures specified:
131131

@@ -142,6 +142,26 @@ let hr = async |x: &str| { do_something(x).await };
142142

143143
When called, they return an anonymous future type corresponding to the (not-yet-executed) body of the closure. These can be awaited like any other future.
144144

145+
The `async Fn` trait bound syntax can be used anywhere a trait bound is allowed, such as:
146+
147+
```rust
148+
/// In return-position impl trait:
149+
fn closure() -> impl async Fn() { async || {} }
150+
151+
/// In trait bounds:
152+
trait Foo<F>: Sized
153+
where
154+
F: async Fn()
155+
{
156+
fn new(f: F) -> Self;
157+
}
158+
159+
/// in GATs:
160+
trait Gat {
161+
type AsyncHasher<T>: async Fn(T) -> i32;
162+
}
163+
```
164+
145165
# Detailed Explanation
146166

147167
### `AsyncFn*`
@@ -409,14 +429,18 @@ error[E0277]: cannot be sent between threads safely
409429
| required by a bound introduced by this call
410430
```
411431

412-
When the RTN RFC is accepted, this RFC specifies that users will be allowed to add RTN-like bounds to type parameters that are also bounded by `async Fn()`, like so:
432+
With the acceptance of the RTN (return-type notation) [RFC 3654](https://github.com/rust-lang/rfcs/pull/3654), this RFC specifies that users will be allowed to add RTN-like bounds to type parameters that are also bounded by `async Fn()`. Concretely, this bound expands to bound both `CallOnceFuture` and `CallRefFuture` (if the latter exists):
413433

414434
```rust
415435
async fn foo(x: F) -> Result<()>
416436
where
417437
F: async Fn(&str) -> Result<()>,
418438
// The future from calling `F` is `Send` and `'static`.
419439
F(..): Send + 'static,
440+
// Which expands to two bounds:
441+
// `for<'a> <F as AsyncFnMut>::CallRefFuture<'a>: Send`
442+
// `<F as AsyncFnOnce>::CallOnceFuture: Send`
443+
// the latter is only if `F` is bounded with `async Fn` or `async FnMut`.
420444
{
421445
tokio::spawn(x("hello, world")).await
422446
}

0 commit comments

Comments
 (0)