Skip to content
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

Bring the Async Rust experience closer to parity with sync Rust #105

Open
5 of 34 tasks
nikomatsakis opened this issue Jul 22, 2024 · 16 comments
Open
5 of 34 tasks

Bring the Async Rust experience closer to parity with sync Rust #105

nikomatsakis opened this issue Jul 22, 2024 · 16 comments

Comments

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Jul 22, 2024

Metadata
Point of contact @tmandry
Team(s) compiler, lang, libs-api, spec, types
Goal document 2025h1/async

Summary

Over the next six months, we will continue bringing Async Rust up to par with "sync Rust" by doing the following:

  • Telling a complete story for the use of async fn in traits, unblocking wide ecosystem adoption,
  • Improving the ergonomics of Pin, which is frequently used in low-level async code, and
  • Preparing to support asynchronous (and synchronous) generators in the language.

Why this goal?

This work continues our drive to improve support for async programming in Rust. In 2024H2 we stabilized async closures; explored the generator design space; and began work on the dynosaur crate, an experimental proc-macro to provide dynamic dispatch for async functions in traits. In 2025H1 our plan is to deliver (1) improved support for async-fn-in-traits, completely subsuming the functionality of the async-trait crate; (2) progress towards sync and async generators, simplifying the creation of iterators and async data streams; (3) and improve the ergonomics of Pin, making lower-level async coding more approachable. These items together start to unblock the creation of the next generation of async libraries in the wider ecosystem, as progress there has been blocked on a stable solution for async traits and streams.

Tasks and status

Overall program management

Return type notation (rust-lang/rust#109417)

Unsafe binders (rust-lang/rust#130516)

Implementable trait aliases

async fn in dyn Trait (rust-lang/rust#133119)

Pin ergonomics

  • Implementation (@eholk)
  • Author RFC (@eholk)
  • Lang-team experiment (lang Team)
  • Lang-team champion (lang Team)

Trait for generators (sync)

Dynosaur 1.0

@nikomatsakis
Copy link
Contributor Author

This issue is intended for status updates only.

For general questions or comments, please contact the owner(s) directly.

@tmandry
Copy link
Member

tmandry commented Jul 30, 2024

Status update: July 30, 2024

Key developments

Blockers

We are able to make some progress in each area, but the biggest upcoming blocker we can see is:

  • Lang team deciding on final syntax for async closure bounds

Help wanted

There will be a call for testing async closures on the Inside Rust blog soon. Please check it out and give them a try in your own async code!

We'd like to see an updated RFC for implementable trait aliases that follows the guidelines laid out in this comment.

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Sep 19, 2024

Executive summary.

We are generally on track with our marquee features: (1) Support for async closures is available on Nightly and the lang team arrived at a tentative consensus to keep the existing syntax (written rationale and formal decision are in progress). We issued a call for testing as well which has so far uncovered no issues. (2) Partial support for Return Type Notation is available on Nightly with the remainder under review. In addition, dynamic dispatch for async functions and experimental async drop work both made implementation progress. Async WG reorganization has made no progress.

Detailed updates

For this year's goal we are focused on three items:

  • Stabilizing async closures:
    • The Async Closures RFC has been accepted and the feature is available for use on Nightly under the async_closure feature gate. We put out a call for testing; so far, no problems have been reported. Stabilization stalled because of a need to resolve the syntax. Lang team has reached a tentative internal consensus in favor of the syntax as implemented (impl async Fn). Next steps are (1) lang team to write up rationale and finalizing syntax decision; (2) author stabilization report.
  • Resolving "Send Bounds" via Return Type Notation:
    • The Return Type Notation RFC has been accepted and partially implemented under the feature gate return_type_notation. Bounds like Trait<method(): Send> are available on Nightly; bounds like Trait::method(): Send will be available once PR #129629 is merged. Next steps are to (1) merge PR #129629; (2) call for testing; and (3) author stabilization report.
  • Dyn dispatch for async functions in traits:
    • Async functions in traits were stabilized last year without support for dynamic dispatch. For this year we plan to release a procedural macro that can help users workaround this limitation; native support is planned for future years. The all important task of selecting a crate name was completed, with dynosaur being chosen. Basic support is now implemented (see this example). Next steps are polish and putting out a call for testing.
  • Async drop experiments:
    • PRs with experimental implementation work for async drop are ready and awaiting review (PR list).

We have not made progress on Async WG reorganization.

@nikomatsakis
Copy link
Contributor Author

Updates:

  • Stabilizing async closures:
    • Lang team discussed syntax and reached preliminary consensus on async Fn, subject to also agreeing to include some of "async type" syntax. The rationale was documented in RFC: introduce the flavor syntactic design pattern rfcs#3710, which is now open and receiving feedback.
    • Next steps are for lang team to accept the RFC and to author stabilization report.
  • Resolving "Send Bounds" via Return Type Notation:
  • Dyn dispatch for async functions in traits:
    • Preliminary implementation work on the dynosaur crate was done. Polish and public call for testing remain the next steps.
  • Async drop experiments
    • There is a PR with pending work awaiting review. @nikomatsakis has agreed to review.
  • Async WG reorganization.
    • No progress. A meeting was scheduled but deferred.

@tmandry
Copy link
Member

tmandry commented Oct 11, 2024

Preliminary implementation work on the dynosaur crate was done. Polish and public call for testing remain the next steps.

The first version of dynosaur was published: https://docs.rs/dynosaur/latest/dynosaur/attr.dynosaur.html

@nikomatsakis
Copy link
Contributor Author

Updates:

  • Stabilizing async closures: The lang team held a design meeting reviewing the Flavor RFC. Conclusion was that @nikomatsakis will make some edits clarifying the RFC's limited intent (e.g., that is defines a namespacing mechanism and not something more involved) and weakening the language around the term "flavor".
  • Resolving send bounds via RTN: No progress.
  • Async drop experiments: @nikomatsakis performed initial review and is continuing to read into the code.
  • Async WG reorganizaiton: @tmandry is drafting an initial proposal.

Next steps:

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Nov 6, 2024

Update:

  • Upon further discussion the lang team decided to close the flavor RFC (RFC: introduce the flavor syntactic design pattern rfcs#3710) and instead to pursue async closure stabilization with the name AsyncFn. The premise for the RFC was that we only wanted to commit to async Fn if we were ready to commit to at least the syntax of async Trait being used more broadly for other traits. There were enough questions raised during discussion to give some members pause as to whether we had worked out enough of the design space to commit to that, and so we decided to opt for a less ambitious stabilization instead to give more time for discussion.

Next steps:

@compiler-errors
Copy link
Member

That stabilization report is up: rust-lang/rust#132706

@nikomatsakis
Copy link
Contributor Author

With respect to return-type notation, the current status is that we landed an extension of return-type notation to cover Self::foo(..): Send in rust-lang/rust#129629 and we are now shaking out the bugs on that. More testing would be helpful, as would reviews on the PRs we've opened already (e.g., rust-lang/rust#132047).

@nikomatsakis
Copy link
Contributor Author

FCP for async closure stabilization has completed. The PR is not yet merged as we are waiting on a reference PR (coming soon), rust-lang/rust#132612 to land, and reviews on the stabilization PR (rust-lang/rust#132706).

@nikomatsakis
Copy link
Contributor Author

Regarding return-type notation, an extension of return-type notation to cover Self::foo(..): Send landed and we landed #132047 which fixes a known ICE. Stabilization PR is now unblocked.

@nikomatsakis
Copy link
Contributor Author

The Dynosaur crate version 0.1.2 was released but some bugs were found post-release. Iteration continues.

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Dec 18, 2024

Final report of the year: In short, we finished the most important item, and made strong progress on most others but have more work to do:

  • Async closures are stabilized (🎉) and will be shipping out on the next nightly. Big kudos to @compiler-errors for driving that.
  • Return Type Notation is implemented and we had a call for experimentation but it has not yet reached stable. This will need to be done.
  • The work for a standardized macro supporting dynamic dispatch made progress but we haven't yet published the complete story or issued a call for experimentation.

In terms of our stretch goals

  • We have had fruitful discussions about the trait for async iteration but do not have widespread consensus, that's on the docker for 2025H1.
  • There is a PR with a prototype implementation for async drop but we didn't account for reviewing bandwidth. @nikomatsakis has done initial reads and is working with PR author to get this done in 2025H1. To be clear though the scope of this is an experiment with the goal of uncovering implementation hurdles. There remains significant language design work before this feature would be considered for stabilization (we don't even have an RFC, and there are lots of unknowns remaining).

@nikomatsakis nikomatsakis modified the milestones: 2024h2, 2025h1 Feb 18, 2025
@nikomatsakis
Copy link
Contributor Author

This is a continuing project goal, and the updates below this comment will be for the new period 2025h1

@nikomatsakis nikomatsakis removed their assignment Feb 18, 2025
@nikomatsakis nikomatsakis moved this to Project goals in Lang team features Feb 21, 2025
@tmandry
Copy link
Member

tmandry commented Feb 26, 2025

Rust 1.85

The first update is the release of Rust 1.85, which had at least two major features that impact Async Rust. The first is async closures, which has been on many people's wish lists for a long time and was expertly moved forward by @compiler-errors over the last year.

The second is the new lifetime capture rules as part of Rust 2024 edition. This should substantially improve the experience of using async Rust anytime a user writes -> impl Future, as it removes the need for + '_ or similar bounds in most cases. It will also lead to an easier to understand language, since those bounds only worked by exploiting the more subtle rules of impl Trait in a way that runs contrary to their actual semantic role in the language. In the 2024 Edition, the subtle rule is gone and we capture all input lifetimes by default, with the ability to use + use<> syntax to opt out. See this blog post for more.

Generators

The lang team held two design meetings on generators, with the outcome of the last one being that we will implement a std::iter::iter! macro (exact path TBD) in the compiler, as a lang team experiment that allows the use of the yield syntax. We decided to go in this direction because we want to reserve gen for self-borrowing and perhaps lending generators, and aren't yet decided on which subset of features to expose under that syntax. This decision interacts with ongoing compiler development that isn't ready yet to enable experimentation with lending.

Our hope is that in the meantime, by shipping iter! we will give people the chance to start using generators in their own code and better understand which limitations people hit in practice.

As you may have noticed, I'm not talking about async generators here. Those are the ultimate goal for the async initiative, but we felt the first step should be clarifying the state of synchronous generators so we can build on that when talking about async ones.

dynosaur

dynosaur v0.1.3 was released, with another release in the works. We think we are approaching a 1.0 release real soon now (tm). At this point you should be able to try it on your crate to enable dyn dispatch for traits with async fn and other -> impl Trait methods. If you need to use it together with #[trait_variant], you may need to wait until the next release when #55 is fixed.

Other

The async project goal was accepted for 2025H1!

@nikomatsakis

This comment has been minimized.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Status: Project goal
Development

No branches or pull requests

3 participants