Tracking issue for RFC 2046, label-break-value · Issue #48594 · rust-lang/rust ·...
source link: https://github.com/rust-lang/rust/issues/48594
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Tracking issue for RFC 2046, label-break-value #48594
2 of 4 tasks
Centril opened this issue on Feb 27, 2018 · 171 comments
2 of 4 tasks
Comments
This is a tracking issue for RFC 2046 (rust-lang/rfcs#2046). Steps: Unresolved questions: |
added B-RFC-approved Approved by a merged RFC but not yet implemented. T-lang Relevant to the language team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature.
labels
Contributor
SoniEx2 commented on Feb 28, 2018
Using "return" would have interesting implications for labeled |
Contributor
est31 commented on Mar 1, 2018
@mark-i-m and @joshtriplett have already spoken out against return, but I'll join in given that it is still apparently an unresolved question.
In C, C++, Java, C#, JavaScript and probably more languages you are usually The "rules to remember" argument works into the other direction really well however. From what I can tell it is a commonality of the mentioned languages as well as Rust that return only applies to functions and nothing else. So if you see a return, you know that a function is being left.
First, I think this happens very rarely as the labeled break feature is admittedly not something that will be used 10 times per 1000 lines. After all, it will only apply to unlabeled breaks that would cross the boundary of the block, not unlabeled breaks inside the block. Second, users of Rust are accustomed to complaints / error messages by the compiler, they will happily fix them! Third (this is the strongest point I think), if instead of labeling a block you wrap it into a loop, you already need to watch out for unlabeled breaks and there is no error message that conveniently lists the break statements, you've got to hunt for them yourself :). |
Contributor
nikomatsakis commented on Mar 1, 2018
This to me is the killer point. break from blocks is a thing in many languages. return from blocks...not so much. |
Contributor
Author
Centril commented on Mar 1, 2018
Personally, I share @joshtriplett's view on using |
Contributor
est31 commented on Apr 15, 2018
Just saying that I'm working on this. Don't need mentor instructions. Just to not duplicate any efforts. Expect a PR soon. |
I'm still in favour of |
Contributor
topecongiro commented on May 21, 2018
Currently (with |
Member
scottmcm commented on May 21, 2018
@topecongiro Yes, I believe it's intentional that this is currently allowed only on plain blocks. It might change in future, but given that this is such a low-level and unusual feature, I'm inclined towards that being a feature rather than a restriction. (On the extreme, I certainly don't want |
Definitely agree. Unsafe + unusual control flow sounds like something to discourage. In a pinch, though, you could use:
Right? |
Actually, altho else does create a new lexical scope, it's not a block. The whole if-else is a block (kinda). So no, you wouldn't get |
Member
eddyb commented on May 22, 2018
|
Contributor
Author
Centril commented on May 22, 2018
That's a great observation! |
Contributor
SoniEx2 commented on May 22, 2018
I think labels should be part of block-containing expressions, not blocks themselves. We already have precedent for this with (Things like |
Member
mark-i-m commented on May 22, 2018
Only if |
Member
eddyb commented on May 23, 2018
@mark-i-m It's equivalent to |
Member
mark-i-m commented on May 23, 2018
Woah, I find that highly unintuitive. I expect |
Member
mark-i-m commented on May 23, 2018
Oh I see... |
Member
mark-i-m commented on May 23, 2018
This is why I don't like labeled break/continue :/ |
Contributor
rpjohnst commented on May 23, 2018
Well, we specifically don't have the ability to label these weird inner blocks, so I don't see the problem. |
Member
mark-i-m commented on May 23, 2018
My confusion was not specific to weird inner blocks, but I don't really want to reopen the discussion. That already happened and the community decided to add it. |
Contributor
SoniEx2 commented on May 24, 2018
Okay, I understand accessibility is a big issue with programming languages... however, labeled break is extremely useful if you write code like me. So, how can we make labeled break more accessible? |
Member
mark-i-m commented on May 24, 2018
That's a great question. Some ideas I had:
As a first (admittedly biased) sample, my last (and first) encounter with labeled break in real code was not stellar: https://github.com/rust-lang/rust/pull/48456/files#diff-3ac60df36be32d72842bf5351fc2bb1dL51. I respectfully suggest that if the original author had put in slightly more effort they could have avoided using labeled break in that case altogether... This is an example of the sort of practice I would like to discourage if possible. |
Contributor
rpjohnst commented on May 24, 2018
That's... not labeled break? |
@jgarvin Not sure about their exact use case, but one issue with that method is it doesn't work properly with @buzmeg In the meantime until this is stabilized, as mentioned in the RFC there is always the alternative of using a loop, e.g. Of course in some very complex cases there is just no real replacement for EDIT: I mistakenly wrote that this RFC would enable certain code that is not possible to write today; I think this used to be true, but I think that now the compiler is smart enough to recognize that a loop will only run once if it ends with |
Contributor
WaffleLapkin commented on May 31
@Coder-256 rust macros are (somewhat) hygienic, so |
This is an effect of two interacting issues If your C-code is
That winds up:
This is one of the few instances where Rust introduces mechanisms for a bug that doesn't exist in C. It's not possible to execute code after the conditional test in C because of the structure of do/while while it's quite possible in the Rust replacement idiom. In addition, the C code has no "break" statements so it's not possible to confuse which break goes where while in the Rust code it's actively difficult to keep track of the various break statements. I'm certainly not going to argue for "goto" as that's simply not possible with Rust semantics. Neverthless, not having do/while makes this a lot uglier than it should be. However, syntax does sometimes matter for humans. Aside: Yes, you can argue that the code shouldn't be written that way in Rust. And you would be correct. However, some of us have to start with legacy codebases before they can be modernized. This isn't theoretical: See: https://github.com/ARMmbed/DAPLink/blob/main/source/daplink/cmsis-dap/DAP.c Of course, I'm not an expert, so it is entirely possible I'm missing something obvious in Rust that would make this discussion moot. If so, I apologize for the noise. |
@buzmeg Why not rename As for flipping the if statements, it's true that you could put code after the test but that's not necessarily a bug, the rust code is just more general about how you want to structure the loop exit test. Obviously if you want behavior equivalent to a do-while loop though it should be the last thing in the loop. I think the code as written is essentially exactly the way it should be written (assuming rust doesn't spawn any new syntax in the near future), and there is a pretty mechanical way to obtain that code by syntactic transformation of the C code you started with. The do-while transformation has already been explained and is easy enough to understand, and the goto transformation looks like this:
==>
This only works for downward goto (for upward goto you would use |
Contributor
clarfonthey commented on Jun 5
I don't think this was explicitly part of the RFC but another thing that might be worth including before stabilisation: right now labels aren't allowed before statements or expressions, particularly ones that feel like blocks, e.g. the below just shows an unhelpful syntax error:
I think that this could be implemented for all expressions since even something weird like the below could be possible:
But obviously, I feel like this would make the most sense to explicitly deny for now and then allow only specific subsets that make sense, like At least until those types of expressions are valid, I think that the parser should accept any |
I used this feature in my code for a loop which needs to check some complex conditions for a special case, and otherwise fall back to a normal case:
|
Stabilization proposalThe feature was implemented in #50045 by @est31 and has been in nightly since 2018-05-16 (over 4 years now). There have been several concerns raised about this feature on the tracking issue (other than the one about tests, which has been fixed, and an interaction with try blocks, which has been fixed). Many different examples of code that's simpler using this feature have been provided:
Additionally, @petrochenkov notes that this is strictly more powerful than labelled loops due to macros which accidentally exit a loop instead of being consumed by the macro matchers: #48594 (comment) @nrc later resolved their concern, mostly because of the aforementioned macro problems. @joshtriplett later resolved his concerns, due to a symmetry between this feature and existing labelled break: #48594 (comment) @withoutboats has regrettably left the language team. @joshtriplett later posted that the lang team would consider starting an FCP given a stabilization report: #48594 (comment) Thus, I move to stabilize label-break-value (RFC 2046). To make it easier to see exactly what changes are proposed, I've also opened a stabilization PR: #99332. This should not be merged until and unless the FCP finishes. ReportInteractions with other featuresLabels follow the hygiene of local variables. label-break-value is permitted within
label-break-value is disallowed within closures, generators, and async blocks:
label-break-value is disallowed on BlockExpression; it can only occur as a LoopExpression:
|
@joshtriplett could you please start an FCP? |
Member
joshtriplett commented on Jul 17
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it.
labels
Really exited about this I don't need it too frequently, but it feels intuitive and there were a bunch of places where it would have meaningfully simplified my code.
Did you intend to show that you can exit
|
Member
jyn514 commented 18 days ago
Hi @cramertj @nikomatsakis @scottmcm - have you gotten a chance to look at
this change? I'm happy to answer questions or do more research.
Message ID: ***@***.***>
…
|
I remembered the labels involved in this as not being hygienic, but when I went to test that out I was pleased to see that I was wrong about that: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=02c73a78c1098db8fe2e8dd1624f205b. So that resolves my biggest worry about this (since I suspect 90% of loop labels in the wild are just One objection here a few years ago mentioned graydon's limits to (some) growth blog post that I wanted to address specifically, since how I see that applying here is different. First, I think we've already paid most of the costs here because of the existence of labelled loops. Second, this is the structured programming scope exiting construct. All of those that we have already -- So this isn't something I want to see often in Rust code, but I think it's well worth supporting for those few places where it's appropriate, since the cost seems to be low to me. For example, I could imagine a r-a refactoring for inlining I still weakly prefer @rfcbot reviewed Oh, one other thing as I was re-skimming the thread. I still consider it a good thing that this requires a block. This isn't the kind of thing that's so pervasive that eliding it is worth allowing. I do agree it would be possible to allow it in more places, but I really don't want that. (This reminds me of attributes, for example -- in general I think it's good to put attributes on blocks, so it's clear to what they apply, rather than support them everywhere and subject people to wondering what |
added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label
rfcbot commented 6 days ago
This is now entering its final comment period, as per the review above. |
removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label
Contributor
nikomatsakis commented 3 days ago
@rfcbot reviewed |
To be clear, I assume it is allowed if both the break and the label are inside the closure/generator/async -- what is forbidden is crossing that boundary? |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
No one assigned
None yet
No milestone
No branches or pull requests
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK