-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Stabilize async_await
in Rust 1.39.0
#63209
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
16df48a
to
c8dd6e7
Compare
This comment has been minimized.
This comment has been minimized.
…sts, r=cramertj Test interaction between `async { ... }` and `?`, `return`, and `break` Per the second checkbox in rust-lang#62121 (comment), test that `async { .. }` blocks: 1. do not allow `break` expressions. 2. get targeted by `return` and not the parent function. 3. get targeted by `?` and not the parent function. Works towards resolving blockers in rust-lang#63209. r? @cramertj
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…s, r=nikomatsakis `async fn` lifetime elision tests Add `async fn` version of the tests in rust-lang#61207 per the first checkbox in rust-lang#62121 (comment). Works towards resolving blockers in rust-lang#63209. r? @nikomatsakis cc @cramertj
Rust 1.38 is scheduled to branch off today, but this PR didn't land yet and there are a bunch of blockers still open. If we still want to stabilize I'd prefer to stabilize cc @rust-lang/lang @rust-lang/release |
…s, r=nikomatsakis `async fn` lifetime elision tests Add `async fn` version of the tests in rust-lang#61207 per the first checkbox in rust-lang#62121 (comment). Works towards resolving blockers in rust-lang#63209. r? @nikomatsakis cc @cramertj
…s, r=nikomatsakis `async fn` lifetime elision tests Add `async fn` version of the tests in rust-lang#61207 per the first checkbox in rust-lang#62121 (comment). Works towards resolving blockers in rust-lang#63209. r? @nikomatsakis cc @cramertj
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
`async_await` is stabilized in rust-lang/rust#63209. This commit fixes `hyper` build with latest nightly compiler.
`async_await` is stabilized in rust-lang/rust#63209. This commit fixes `hyper` build with latest nightly compiler.
@golddranks My understanding of that comment is that it's possible to cause UB in async await with |
@golddranks Yep; It was considered on a language team meeting and our understanding matches @XAMPPRocky's re. |
@Centril I think this understanding is flawed. As already laid out in #63209 (comment), While we don't yet have these aliasing restrictions fully fleshed out, many (all?) reasonable forms they could take appear incompatible with async/await (at least as it is currently lowered), since in @comex's example it leads to two "clearly distinct" pointers aliasing. This is clearly visible even at the MIR level, after the state machine transform. Thus the only hope I see for this issue "just disappearing" without wider impact is if we find a different way to lower async fns/blocks that side-steps the issue and still delivers everything else we want from async fns. This seems unlikely to me, tbh. If that doesn't happens, stabilizing async/await doesn't simply mean we forever barred from re-enabling |
@rkruppe Thanks for a detailed write-up.
This is my understanding as well and I did take the time to read up on the history of removing the flag before stabilizing.
Yes, I agree and it would be very unfortunate not to have the desired optimizations outside
Agreed. And at least
A I should also note that @cramertj made a comment re. removing |
|
@Centril Should have been expected that std::future::Future is not really stable until polished async/await lands. If anything, it's better to change it now, rather than after it together with async/await go live in the ecosystem. |
We have a commitment to stability and cannot break folks who use |
I thought it was bizarre that
Soundness bugs are an exception, right? Unintentionally altering the languages memory model would seem to be in a similar category to me. It's unfortunate, but unless a workaround can found, I think breaking changes to
The desire for Regardless of the decision taken, I think this merits serious consideration rather just "It's stable: there's nothing we can do now". |
@Centril I know that Rust team takes stability guarantees seriously. But realistically speaking, most (the only?) current It's better to propagate breaking changes across a very small community now rather than suffer when it will really be too late to fix. |
I agree it was not ideal from a process POV where the main issue was Although, for what it's worth, I did ask some vague questions about exactly this at the time, #55766 (comment) which was replied to in #55766 (comment) which does not seem true today. Unfortunately, Ralf did not have a time machine. In the end, it was just happenstance that we noticed this now which is mainly because the UCG got to this point. We could have easily stabilized all of pin, futures, async_await and found this out 2 months later. Mistakes where made, and we have to live with them.
Yes, that didn't help. In the future I think that we need to be clearer that stakeholders pushing for a feature need to be part of testing it out on nightly.
They are, but we still have to be careful even in the even of a soundness bug to deal with the fallout in a graceful way.
@RalfJung's comments in rust-lang/unsafe-code-guidelines#148 (comment) suggests that a workaround can be found to recover
Certainly; For example, I don't expect I will personally use this feature that much, at least not now.
See above re. @RalfJung's notes. I believe we should be able to recover
For what it's worth I have debated this internally and given it a non-trivial amount of thought.
Sure, it's always true that a breaking change is easier to propagate when fewer rely on them. However, I believe you are underestimating the disruption this would cause both to code and to trust in our leadership. |
I'd like to point out that one of the foremost things that would prevent erosion of trust towards the Rust leadership and decision process, is to have someone with understanding of the matter as thorough as possible, to write a summarisation that considers the Rust memory model, what is being lost, what is not, what can be done, what are the possibilities for action considering the leadership/release/stabilisation model et cetera. It's FUD that is the poison, and information from knowledgeable and authoritative source is the best remedy. Things concerning Rust memory model and optimisation potential sound serious, so I think they should be taken quite seriously. |
Like (I think) @rkruppe, I read this as saying that "soundness bugs on the Rust side with
So, that note is my plan for how to approach the problem, when/if me or someone else gets around to actually do that. Note that e.g. Btw,
I think they are. The trouble is, we are still very early in exploring the design space for Rust memory models. It's basically impossible to say anything precise. |
I have a prototype here (https://github.com/gnzlbg/break_aw) that does not use thread-local storage and that allows LLVM to optimize across the yield point. I haven't been able to cause a misoptimization yet. |
`async_await` is stabilized in rust-lang/rust#63209.
Is this a limitation of your current approach to resolving this issue, which could eventuantally removed? Or is this a fundamental restriction imposed the interaction of Pin, self-referential generators, and mutable references? |
I believe they still are soundness bugs especially in the cases where async-await, generators, and pin are not involved. At least this is my personal opinion and that of the language team historically (to my knowledge) and we haven't actively changed our minds here. |
Related, Issue #54878 and Issue #45029 track |
@jeffvandyke We did emit noalias for panic=abort for a while but had to revert that, see #54639 |
I think this is fundamental. Adding |
Please direct further discussion to #63818. |
Pkgsrc changes: * Remove patch which no longer applies (but what about RPATH?) * Adapt a few patches to changed files upstream. Upstream changes: Version 1.39.0 (2019-11-07) =========================== Language -------- - [You can now create `async` functions and blocks with `async fn`, `async move {}`, and `async {}` respectively, and you can now call `.await` on async expressions.][63209] - [You can now use certain attributes on function, closure, and function pointer parameters.][64010] These attributes include `cfg`, `cfg_attr`, `allow`, `warn`, `deny`, `forbid` as well as inert helper attributes used by procedural macro attributes applied to items. e.g. ```rust fn len( #[cfg(windows)] slice: &[u16], #[cfg(not(windows))] slice: &[u8], ) -> usize { slice.len() } ``` - [You can now take shared references to bind-by-move patterns in the `if` guards of `match` arms.][63118] e.g. ```rust fn main() { let array: Box<[u8; 4]> = Box::new([1, 2, 3, 4]); match array { nums // ---- `nums` is bound by move. if nums.iter().sum::<u8>() == 10 // ^------ `.iter()` implicitly takes a reference to `nums`. => { drop(nums); // ----------- Legal as `nums` was bound by move and so we have ownership. } _ => unreachable!(), } } ``` Compiler -------- - [Added tier 3\* support for the `i686-unknown-uefi` target.][64334] - [Added tier 3 support for the `sparc64-unknown-openbsd` target.][63595] - [rustc will now trim code snippets in diagnostics to fit in your terminal.] [63402] **Note** Cargo currently doesn't use this feature. Refer to [cargo#7315][cargo/7315] to track this feature's progress. - [You can now pass `--show-output` argument to test binaries to print the output of successful tests.][62600] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries --------- - [`Vec::new` and `String::new` are now `const` functions.][64028] - [`LinkedList::new` is now a `const` function.][63684] - [`str::len`, `[T]::len` and `str::as_bytes` are now `const` functions.][63770] - [The `abs`, `wrapping_abs`, and `overflowing_abs` numeric functions are now `const`.][63786] Stabilized APIs --------------- - [`Pin::into_inner`] - [`Instant::checked_duration_since`] - [`Instant::saturating_duration_since`] Cargo ----- - [You can now publish git dependencies if supplied with a `version`.] [cargo/7237] - [The `--all` flag has been renamed to `--workspace`.][cargo/7241] Using `--all` is now deprecated. Misc ---- - [You can now pass `-Clinker` to rustdoc to control the linker used for compiling doctests.][63834] Compatibility Notes ------------------- - [Code that was previously accepted by the old borrow checker, but rejected by the NLL borrow checker is now a hard error in Rust 2018.][63565] This was previously a warning, and will also become a hard error in the Rust 2015 edition in the 1.40.0 release. - [`rustdoc` now requires `rustc` to be installed and in the same directory to run tests.][63827] This should improve performance when running a large amount of doctests. - [The `try!` macro will now issue a deprecation warning.][62672] It is recommended to use the `?` operator instead. - [`asinh(-0.0)` now correctly returns `-0.0`.][63698] Previously this returned `0.0`. [62600]: rust-lang/rust#62600 [62672]: rust-lang/rust#62672 [63118]: rust-lang/rust#63118 [63209]: rust-lang/rust#63209 [63402]: rust-lang/rust#63402 [63565]: rust-lang/rust#63565 [63595]: rust-lang/rust#63595 [63684]: rust-lang/rust#63684 [63698]: rust-lang/rust#63698 [63770]: rust-lang/rust#63770 [63786]: rust-lang/rust#63786 [63827]: rust-lang/rust#63827 [63834]: rust-lang/rust#63834 [63927]: rust-lang/rust#63927 [63933]: rust-lang/rust#63933 [63934]: rust-lang/rust#63934 [63938]: rust-lang/rust#63938 [63940]: rust-lang/rust#63940 [63941]: rust-lang/rust#63941 [63945]: rust-lang/rust#63945 [64010]: rust-lang/rust#64010 [64028]: rust-lang/rust#64028 [64334]: rust-lang/rust#64334 [cargo/7237]: rust-lang/cargo#7237 [cargo/7241]: rust-lang/cargo#7241 [cargo/7315]: rust-lang/cargo#7315 [`Pin::into_inner`]: https://doc.rust-lang.org/std/pin/struct.Pin.html#method.into_inner [`Instant::checked_duration_since`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_duration_since [`Instant::saturating_duration_since`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.saturating_duration_since
Here we stabilize:
async fn
s,<expr>.await
expression form,async move? { ... }
block form.Closes #62149.
Closes #50547.
All the blockers are now closed.
Self
treats type's lifetime parameters as'static
#61949; PR in typeck: Prohibit RPIT types that inherit lifetimes #62849.ParamName
to track in-scope lifetimes instead of Ident #63501&self
lifetime elision with two parameters does not work withasync fn
#63388; PR in handle elision in async fn correctly #63499'_
elision do not interact correctly #63500; PR in useParamName
to track in-scope lifetimes instead of Ident #63501async { ... }
and?
,return
, andbreak
#63387):-
?
-
return
inasync
blocks-
break
async fn
s instead). PR inasync fn
lifetime elision tests #63383r? @cramertj