-
Notifications
You must be signed in to change notification settings - Fork 302
Inside Rust: Async Working Group July update #1112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
nikomatsakis
wants to merge
3
commits into
rust-lang:master
from
nikomatsakis:2023-06-async-wg-june-update
Closed
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
--- | ||
layout: post | ||
title: "Async Working Group June update" | ||
author: Niko Matsakis and Tyler Mandry | ||
team: The Rust Async Working Group <https://www.rust-lang.org/governance/wgs/wg-async> | ||
--- | ||
|
||
This is the June update from the Async Working Group of the Rust Programming Language. In May, we [laid out our plans for the year][may]. Over the last month, we have gotten a clearer picture of the stabilization strategy. The current plan is to stabilize the full async function in trait MVP in two phases: | ||
|
||
[may]: https://blog.rust-lang.org/inside-rust/2023/05/03/stabilizing-async-fn-in-trait.html | ||
|
||
* Phase 1: support `async fn` and `-> impl Trait` in traits and impls (target: Rust 1.73, Oct 5). | ||
* Phase 2: support "send bounds", likely (but not necessarily) through ["return type notation"][rtn] (target: Rust 1.74, Nov 16). | ||
|
||
[rtn]: https://blog.rust-lang.org/inside-rust/2023/05/03/stabilizing-async-fn-in-trait.html#mvp-part-2-send-bounds-and-associated-return-types | ||
|
||
The first phase covers the ability to write `async fn` and `-> impl Trait` in both traits and impls, roughly as described in [RFC 3185] and [RFC 3425]. These features have been implemented for some time and they are not controversial, though we are still working to do a final triage of bugs and blockers. This first phase provides functionality roughly equivalent to the existing `#[async_trait]` macro and, as such, it's enough for a great many use cases. | ||
|
||
[RFC 3185]: https://rust-lang.github.io/rfcs/3185-static-async-fn-in-trait.html | ||
[RFC 3425]: https://github.com/rust-lang/rfcs/pull/3425 | ||
|
||
The second phase will add support for the ability to put bounds on the futures returned by async functions. Our case studies found that this was a common need as well, particularly for traits which would appear in the standard library, as such traits do not want to return futures to always be `Send`. We have an experimental implementation of ["return type notation"][rtn] on master, but the best solution for the sends bound problem is still under some debate. | ||
|
||
## When to stabilize async functions in traits | ||
|
||
One of the key questions we were considering was whether to hold off on stabilizing async functions in traits until we were ready to stabilize a solution for the "send bounds" problem as well. On the one hand, our [case studies][cs] showed that send bounds would be important to many users. Moreover, the stabilization of async functions in traits is going to be a big deal and many users will try using them. We don't want them to get frustrated with missing functionality. | ||
|
||
[cs]: https://github.com/rust-lang/async-fundamentals-initiative/tree/master/evaluation/case-studies | ||
|
||
On the other hand, a true "send bounds" solution is only needed when you wish to have a trait that *may* or *may not* return `Send` futures. Many users can get by with traits that either *always* require `Send` or *never* require `Send`, as demonstrated by the `#[async_trait]` macro. | ||
|
||
Rust has a tradition of making new functionality available incrementally rather than waiting for perfection, and it's always served us well (async functions themselves are an example of this, as is `-> impl Trait` in other functions). Moreover, while it is possible to emulate `async fn` using `-> impl Future`, the translation can be subtle. We feared that releasing `-> impl Trait` support without `async fn` would lead to people misusing the former to emulate the latter. On balance, we felt that it would be better to release async functions as quickly as possible. | ||
|
||
## What Phase 1 enables: using Async Functions in Traits | ||
|
||
Phase 1 provides enough functionality to make it possible to write traits that contain async functions that are either *always* `Send` or *never* `Send`. This makes it roughly equivalent to what you can do with the `#[async_trait]` macro, but potentially more efficient, since you can avoid boxing when using static dispatch. It is also possible to fill in support for `dyn` dispatch using a macro. We expect that many async trait users in these early phases will wind up using some sort of macros to remove some boilerplate, and are discussing shipping a rust-lang crate that provides these common utilities. | ||
|
||
For example, consider the `HealthCheck` trait shown here: | ||
|
||
```rust | ||
trait HealthCheck { | ||
async fn check(&mut self); | ||
} | ||
|
||
impl HealthCheck for MyType { | ||
async fn check(&mut self) { /* ... */ } | ||
} | ||
``` | ||
|
||
As written, this `HealthCheck` trait is not guaranteed to return `Send` futures. Using explicit `-> impl Future` notation, however, it is possible to make a variant of the trait that *does* guarantee returning `Send` futures; better yet, it's still possible to write `async fn` in the impl: | ||
|
||
```rust | ||
trait SendHealthCheck { | ||
fn check(&mut self) -> impl Future<Output = ()> + Send + '_; | ||
} | ||
|
||
impl SendHealthCheck for MyType { | ||
async fn check(&mut self) { /* ... */ } | ||
} | ||
``` | ||
|
||
If the async fn is not `Send`, the [compiler would error](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=0948f287cd7fae0c8ddad3a586b698f4). | ||
|
||
## What Phase 2 enables: the "send bound" problem | ||
|
||
Phase 1 is great, but it doesn't support writing traits that only *sometimes* require `Send` bounds. This is really needed for traits that will be used in highly generic contexts, like the standard library. To support those kinds of cases, we really want a solution to the "send bounds" problem. We currently have an experimental implementation of one proposal, return type notation, and this month a draft RFC was [posted to Zulip](https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-async/topic/associated.20return.20types.20draft.20RFC/near/356796689) and then reviewed in a [lang team design meeting](https://github.com/rust-lang/lang-team/blob/master/design-meeting-minutes/2023-05-24-return-type-notation.md). That conversation turned up a few other ideas that hadn't been considered yet, and we are talking about them before settling on a final direction. The goal is to open an RFC for the final approach, whatever that winds up being, later this month. | ||
|
||
## Timeline and Roadmap | ||
|
||
To provide an overview of our progress and the expected timeline, here is our updated roadmap for stabilizing RPITIT, async functions in traits, and addressing the "send bounds" problem: | ||
|
||
- [x] MVP implementation | ||
- [x] Case study evaluations complete | ||
- [x] Accepted RFC for RPITIT (target: 2023-05-31) | ||
- [ ] Evaluation period and bug fixing (target: 2023-06-30) | ||
- [ ] Stabilization report for AFIT authored (target: 2023-07-01) | ||
- [ ] Authored RFC for RTN (target: 2023-07-01) | ||
- [ ] Stabilization complete for 1.73.0 (target: 2023-07-21) | ||
- [ ] Accepted RFC for RTN (target: 2023-08-01) | ||
- [ ] Stabilization report for RTN authored (target: 2023-08-29) | ||
- [ ] Stabilization complete for RTN in 1.74.0 (target: 2023-09-26) | ||
|
||
We are working diligently to meet these targets and ensure a smooth and successful stabilization process. | ||
|
||
## Conclusion | ||
|
||
The Async Working Group is focused on stabilizing RPITIT and async functions in traits together for the Rust 1.73.0 release. We encourage you to test these features, provide feedback, and report any issues you encounter. The "send bounds" problem is also being actively discussed, and we expect to propose a solution soon. Thank you for your support and contributions as we strive to shape the future of asynchronous programming in Rust. | ||
|
||
Stay tuned for further updates from the Async Working Group as we progress towards the Rust 1.73.0 release. Together, let's make Rust an even better language for async programming! |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.