Skip to content

Commit 5973093

Browse files
Reserve some space for async Fn bounds not converging on consensus
1 parent cb803f0 commit 5973093

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

text/3668-async-closures.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# Summary
1111
[summary]: #summary
1212

13-
This RFC adds an `async` bound modifier to the `Fn` family of trait bounds. The combination desugars to a set of unstable `AsyncFn{,Mut,Once}` traits that parallel the current `Fn{,Mut,Once}` traits.
13+
This RFC adds an `async` bound modifier to the `Fn` family of trait bounds. The combination currently desugars to a set of unstable `AsyncFn{,Mut,Once}` traits that parallel the current `Fn{,Mut,Once}` traits.
1414

1515
These traits give users the ability to express bounds for async callable types that are higher-ranked, and allow async closures to return futures which borrow from the closure's captures.
1616

@@ -170,7 +170,7 @@ trait Gat {
170170

171171
### `AsyncFn*`
172172

173-
This RFC introduces a family of `AsyncFn` traits. These traits are intended to remain unstable to name or implement, just like the `Fn` traits. Nonetheless, we'll describe the details of these traits so as to explain the user-facing features enabled by them.
173+
This RFC begins by introducing a family of `AsyncFn` traits for the purposes of demonstrating the lending behavior of async closures. These traits are intended to remain unstable to name or implement, just like the `Fn` traits. Nonetheless, we'll describe the details of these traits so as to explain the user-facing features enabled by them.
174174

175175
The definition of the traits is (modulo `rustc_` attributes, and the `"rust-call"` ABI):
176176

@@ -248,6 +248,8 @@ where
248248

249249
### `async` bound modifier on `Fn()` trait bounds
250250

251+
(**note**: See the blocking concern, which reflects that this remains an open question. Repeating the blocking concern: within this RFC, we generally name the user-facing semantics of async trait bounds as `async Fn*`, and we use the name `AsyncFn*` for the internal details of the trait implementation for the purpose of demonstrating the lending behavior.)
252+
251253
The `AsyncFn*` traits specified above are nameable via a new `async` bound modifier that is allowed on `Fn` trait bounds. That is, `async Fn*() -> T` desugars to `AsyncFn*() -> T` in bounds, where `Fn*` is one of the three flavors of existing function traits: `Fn`/`FnMut`/`FnOnce`.
252254

253255
This RFC specifies the modification to the _TraitBound_ nonterminal in the grammar:
@@ -561,6 +563,8 @@ let _ = || {
561563

562564
### Why not `F: AsyncFn() -> T`, naming `AsyncFn*` directly?
563565

566+
(**note**: See the blocking concern, which reflects that this remains an open question.)
567+
564568
Reusing the `async` keyword allows users to understand what an `async Fn() -> T` trait bound does by analogy, since they already should know that adding `async` to some `fn foo() -> T` makes it return an `impl Future<Output = T>` instead of the type `T`.
565569

566570
### Wouldn't `F: AsyncFn() -> T` save more space for `async` trait bound modifiers?
@@ -675,6 +679,10 @@ Fixing this is a follow-up goal that we're interested in pursuing in the near fu
675679
# Unresolved questions
676680
[unresolved-questions]: #unresolved-questions
677681

682+
### What do we call the trait?
683+
684+
There is some discussion about whether to call the bound `T: AsyncFn()` or `T: async Fn()`. As stated above, there is not full consensus about whether `async Fn()` is the syntax we want to commit to name these bounds, but for the purposes of decoupling the fact that `async Fn` is the user-observable trait family, and `AsyncFn` is the traits of the implementation detail, this RFC names them separately.
685+
678686
### `? for<'a>` and its interaction with `async`
679687

680688
Currently on nightly, we parse the `async` trait bound modifier along with `?` (called polarity) *before* the `for<'a>` lifetime binders. This probably should get fixed so that the binder occurs on the *outside* of the trait, like so:

0 commit comments

Comments
 (0)