-
Notifications
You must be signed in to change notification settings - Fork 1.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
try_trait_v2: A new design for the ? desugaring #3058
Conversation
This looks great. Nominating for the next design meeting. |
Wow! I'm unsure if I'm qualified to comment on a RFC, but for the record, I believe this covers everything discussed here and then some. This looks great! |
Thanks Nokel81 for spotting this.
This seems like a good design, but I have a few concerns:
|
Thanks for the reply! Splitting out the
That section is no longer in the template: https://github.com/rust-lang/rfcs/blob/master/0000-template.md
Yeah, I discuss holder types for types that aren't generic in I think what pushed me to using the same type for both things is that a "residual" type (to use Niko's word) of some sort is needed for just about any type -- Suppose we wanted Even for |
This would be useful to have something like |
62084c0
to
6560a37
Compare
Thanks mbartlett21 & ehuss & tmccombs!
6560a37
to
aa62c5b
Compare
Maybe I'm not qualified to speak on this, but I find this RFC really confusing. Perhaps it's because I'm a non-native english speaker, but I fail to follow its whole reasoning about the |
I am I native english speaker, and I do have to agree with @castroed47 a little. I did find the description for |
I'm also a native english speaker and I also had a really hard time trying (heh) to understand the way all of these traits were set up. In hindsight my explanation is super rambly but maybe it'll help clarify what I think are the biggest issues with this setup. Most of them aren't about the spirit of the implementation (which, after thinking about it, I am fine with), but rather the actual implementation itself and the naming. Like, I don't actually have a big problem with the general idea of this, and especially I feel like the I know you didn't mention any bikeshedding and I don't think this should be considered as a suggestion of names, but I do want to point out how the flow is very confusing with the existing methods:
The names do not have any consistency at all, and don't represent at all what's happening during the flow. Although the implementation mentions control flow decisions, it doesn't at all mention what flow these decisions are controlling. The term "bubble" implies that they're part of a "bubble" flow but we've already decided to call the flow a try flow, so it seems to imply that we're talking about an entirely different flow even though we're not. Now, let's look at the types:
Basically⦠the entire flow is designed to sidestep the fact that we don't have GATs. The whole purpose of the holder is to have a single type that represents what can happen in the control flow, and then get the associated type associated with the right continue to finish things off. After thinking about it, going away from GATs actually is a good idea (your So⦠here's my general description of what we're trying to do with this implementation. I'm going to use
Now, there are a few caveats:
Note that in both cases, we have a conversion, but the direction of the conversions is switched. The way that this implementation solves the second problem is with a Really, what we want is our "try" trait to have "exit with break" have a signature like |
This comment has been minimized.
This comment has been minimized.
(Not sure if what I said counts as bikeshedding; I mention names as a way of discussing issues with structure but tried not to strictly discuss how the trait should specifically be named.) |
I think @clarfonthey's comment really clarifies thing a lot, at least for me. If I'm understanding this correctly, |
Constructive criticism after my second or third pass. The section "Avoiding interconversion with a custom
The point of Relatedly, changing the
I'm still assimilating the technical aspects, but those are my initial thoughts on (mostly) the presentation. Hopefully they're useful. I'm looking forward to the possibility of custom |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
Huzzah! The rust language and library teams have decided to accept this RFC. To track further For |
β¦m-basics, r=m-ou-se Stabilize `ops::ControlFlow` (just the type) Tracking issue: rust-lang#75744 (which also tracks items *not* closed by this PR). With the new `?` desugar implemented, [it's no longer possible to mix `Result` and `ControlFlow`](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=13feec97f5c96a9d791d97f7de2d49a6). (At the time of making this PR, godbolt was still on the 2021-05-01 nightly, where you can see that [the mixing example compiled](https://rust.godbolt.org/z/13Ke54j16).) That resolves the only blocker I know of, so I'd like to propose that `ControlFlow` be considered for stabilization. Its basic existence was part of rust-lang/rfcs#3058, where it got a bunch of positive comments (examples [1](rust-lang/rfcs#3058 (comment)) [2](rust-lang/rfcs#3058 (review)) [3](rust-lang/rfcs#3058 (comment)) [4](rust-lang/rfcs#3058 (comment))). Its use in the compiler has been well received (rust-lang#78182 (comment)), and there are ecosystem updates interested in using it (rust-itertools/itertools#469 (comment), jonhoo/rust-imap#194). As this will need an FCP, picking a libs member manually: r? `@m-ou-se` ## Stabilized APIs ```rust #[derive(Debug, Clone, Copy, PartialEq)] pub enum ControlFlow<B, C = ()> { /// Exit the operation without running subsequent phases. Break(B), /// Move on to the next phase of the operation as normal. Continue(C), } ``` As well as using `?` on a `ControlFlow<B, _>` in a function returning `ControlFlow<B, _>`. (Note, in particular, that there's no `From::from`-conversion on the `Break` value, the way there is for `Err`s.) ## Existing APIs *not* stabilized here All the associated methods and constants: `break_value`, `is_continue`, `map_break`, [`CONTINUE`](https://doc.rust-lang.org/nightly/std/ops/enum.ControlFlow.html#associatedconstant.CONTINUE), etc. Some of the existing methods in nightly seem reasonable, some seem like they should be removed, and some need more discussion to decide. But none of them are *essential*, so [as in the RFC](https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#methods-on-controlflow), they're all omitted from this PR. They can be considered separately later, as further usage demonstrates which are important.
@tvallotton People are working hard on improving the language. I don't know why you felt the need to add a sarcastic "thanks" in an edit of your comment, or why you think this is 'the only useful feature of try_trait', but snarky comments like that are not welcome here. I've hidden your comment. |
β¦=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
β¦=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
Rollup merge of rust-lang#128954 - zachs18:fromresidual-no-default, r=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
Replace RFC #1859,
try_trait
, with a new design for the currently-unstableTry
trait and desugaring for the?
operator.πΌοΈ Rendered πΌοΈ
π RFC Book π
π Tracking Issue π
Update 2021-02-07: This was almost completely rewritten. If you're looking to read the discussion, you might want to jump to #3058 (comment) for the comments that are about the current version of the text.
I've also made a proof-of-concept implementation: https://github.com/scottmcm/rust/pull/2/files
Thanks to everyone who discussed this problem space in the original RFC thread, in the
try_trait
tracking issue, in zulip topics, in IRLO threads, on Discord, and elsewhere. There are far too many to mention individually.This RFC has at least three major bikesheds. To focus on the motivations, problem space, and proposed semantics of this change initially, please hold off on feedback about item names until 2021-01-18. I reserve the right to hide bikeshedding posts made before then.Note also that this RFC intentionally makes no decisions about try blocks or yeet expressions; they're only mentioned in the explicitly non-normative "future possibilities" section. So please refrain from making any comments about their desirability.