-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for RFC 2046, label-break-value #48594
Comments
Using "return" would have interesting implications for labeled |
@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 :). |
This to me is the killer point. break from blocks is a thing in many languages. return from blocks...not so much. |
Personally, I share @joshtriplett's view on using |
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 |
Implement label break value (RFC 2046) Implement label-break-value (#48594).
Currently (with |
@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: 'a: {
unsafe {...}
} 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 |
|
That's a great observation! |
I think labels should be part of block-containing expressions, not blocks themselves. We already have precedent for this with (Things like |
Only if |
@mark-i-m It's equivalent to |
Woah, I find that highly unintuitive. I expect |
Oh 🤦♂️ I see... |
This is why I don't like labeled break/continue :/ |
Well, we specifically don't have the ability to label these weird inner blocks, so I don't see the problem. |
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. |
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? |
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. |
That's... not labeled break? |
@eddyb you're right, I misread https://doc.rust-lang.org/nightly/reference/expressions/match-expr.html#match-expressions. fn labeled_match() {
if true 'b: { //~ ERROR block label not supported here |
# Stabilization proposal The feature was implemented in rust-lang#50045 by est31 and has been in nightly since 2018-05-16 (over 4 years now). There are [no open issues][issue-label] other than the tracking issue. There is a strong consensus that `break` is the right keyword and we should not use `return`. 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). 1. nrc's original comment about cost-benefit analysis: rust-lang#48594 (comment) 2. joshtriplett's comments about seeing use cases: rust-lang#48594 (comment) 3. withoutboats's comments that Rust does not need more control flow constructs: rust-lang#48594 (comment) Many different examples of code that's simpler using this feature have been provided: - A lexer by rpjohnst which must repeat code without label-break-value: rust-lang#48594 (comment) - A snippet by SergioBenitez which avoids using a new function and adding several new return points to a function: rust-lang#48594 (comment). This particular case would also work if `try` blocks were stabilized (at the cost of making the code harder to optimize). - Several examples by JohnBSmith: rust-lang#48594 (comment) - Several examples by Centril: rust-lang#48594 (comment) - An example by petrochenkov where this is used in the compiler itself to avoid duplicating error checking code: rust-lang#48594 (comment) - Amanieu recently provided another example related to complex conditions, where try blocks would not have helped: rust-lang#48594 (comment) 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: rust-lang#48594 (comment) nrc later resolved their concern, mostly because of the aforementioned macro problems. joshtriplett suggested that macros could be able to generate IR directly (rust-lang#48594 (comment)) but there are no open RFCs, and the design space seems rather speculative. joshtriplett later resolved his concerns, due to a symmetry between this feature and existing labelled break: rust-lang#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: rust-lang#48594 (comment) [issue-label]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AF-label_break_value+ ## Report + Feature gate: - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/src/test/ui/feature-gates/feature-gate-label_break_value.rs + Diagnostics: - https://github.com/rust-lang/rust/blob/6b2d3d5f3cd1e553d87b5496632132565b6779d3/compiler/rustc_parse/src/parser/diagnostics.rs#L2629 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L749 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L1001 - https://github.com/rust-lang/rust/blob/111df9e6eda1d752233482c1309d00d20a4bbf98/compiler/rustc_passes/src/loops.rs#L254 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L2079 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L1569 + Tests: - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_continue.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_unlabeled_break.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_illegal_uses.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/lint/unused_labels.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/run-pass/for-loop-while/label_break_value.rs ## Interactions with other features Labels follow the hygiene of local variables. label-break-value is permitted within `try` blocks: ```rust let _: Result<(), ()> = try { 'foo: { Err(())?; break 'foo; } }; ``` label-break-value is disallowed within closures, generators, and async blocks: ```rust 'a: { || break 'a //~^ ERROR use of unreachable label `'a` //~| ERROR `break` inside of a closure } ``` label-break-value is disallowed on [_BlockExpression_]; it can only occur as a [_LoopExpression_]: ```rust fn labeled_match() { match false 'b: { //~ ERROR block label not supported here _ => {} } } macro_rules! m { ($b:block) => { 'lab: $b; //~ ERROR cannot use a `block` macro fragment here unsafe $b; //~ ERROR cannot use a `block` macro fragment here |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here } } fn foo() { m!({}); } ``` [_BlockExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/block-expr.html [_LoopExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/loop-expr.html
… r=petrochenkov Stabilize `#![feature(label_break_value)]` See the stabilization report in rust-lang#48594 (comment).
… r=petrochenkov Stabilize `#![feature(label_break_value)]` See the stabilization report in rust-lang#48594 (comment).
# Stabilization proposal The feature was implemented in rust-lang/rust#50045 by est31 and has been in nightly since 2018-05-16 (over 4 years now). There are [no open issues][issue-label] other than the tracking issue. There is a strong consensus that `break` is the right keyword and we should not use `return`. 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). 1. nrc's original comment about cost-benefit analysis: rust-lang/rust#48594 (comment) 2. joshtriplett's comments about seeing use cases: rust-lang/rust#48594 (comment) 3. withoutboats's comments that Rust does not need more control flow constructs: rust-lang/rust#48594 (comment) Many different examples of code that's simpler using this feature have been provided: - A lexer by rpjohnst which must repeat code without label-break-value: rust-lang/rust#48594 (comment) - A snippet by SergioBenitez which avoids using a new function and adding several new return points to a function: rust-lang/rust#48594 (comment). This particular case would also work if `try` blocks were stabilized (at the cost of making the code harder to optimize). - Several examples by JohnBSmith: rust-lang/rust#48594 (comment) - Several examples by Centril: rust-lang/rust#48594 (comment) - An example by petrochenkov where this is used in the compiler itself to avoid duplicating error checking code: rust-lang/rust#48594 (comment) - Amanieu recently provided another example related to complex conditions, where try blocks would not have helped: rust-lang/rust#48594 (comment) 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: rust-lang/rust#48594 (comment) nrc later resolved their concern, mostly because of the aforementioned macro problems. joshtriplett suggested that macros could be able to generate IR directly (rust-lang/rust#48594 (comment)) but there are no open RFCs, and the design space seems rather speculative. joshtriplett later resolved his concerns, due to a symmetry between this feature and existing labelled break: rust-lang/rust#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: rust-lang/rust#48594 (comment) [issue-label]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AF-label_break_value+ ## Report + Feature gate: - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/src/test/ui/feature-gates/feature-gate-label_break_value.rs + Diagnostics: - https://github.com/rust-lang/rust/blob/6b2d3d5f3cd1e553d87b5496632132565b6779d3/compiler/rustc_parse/src/parser/diagnostics.rs#L2629 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L749 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L1001 - https://github.com/rust-lang/rust/blob/111df9e6eda1d752233482c1309d00d20a4bbf98/compiler/rustc_passes/src/loops.rs#L254 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L2079 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L1569 + Tests: - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_continue.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_unlabeled_break.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_illegal_uses.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/lint/unused_labels.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/run-pass/for-loop-while/label_break_value.rs ## Interactions with other features Labels follow the hygiene of local variables. label-break-value is permitted within `try` blocks: ```rust let _: Result<(), ()> = try { 'foo: { Err(())?; break 'foo; } }; ``` label-break-value is disallowed within closures, generators, and async blocks: ```rust 'a: { || break 'a //~^ ERROR use of unreachable label `'a` //~| ERROR `break` inside of a closure } ``` label-break-value is disallowed on [_BlockExpression_]; it can only occur as a [_LoopExpression_]: ```rust fn labeled_match() { match false 'b: { //~ ERROR block label not supported here _ => {} } } macro_rules! m { ($b:block) => { 'lab: $b; //~ ERROR cannot use a `block` macro fragment here unsafe $b; //~ ERROR cannot use a `block` macro fragment here |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here } } fn foo() { m!({}); } ``` [_BlockExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/block-expr.html [_LoopExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/loop-expr.html
…henkov Stabilize `#![feature(label_break_value)]` See the stabilization report in rust-lang/rust#48594 (comment).
Looks like this was merged for 1.65 in #99332 ! |
Hm, is it intentional that fn _f() {
let f = 'b: { break 'b 92 };
assert_eq!(f, 92);
}
async fn _g() {
let f = async { return 92 };
assert_eq!(f.await, 92);
} |
Yeah it seems a bit weird at first impression, but IMO they are closer to closures than to sync blocks. Like closures, This will print bar and then foo: #[tokio::main]
async fn main() {
let f = async { println!("foo"); return 92; };
println!("bar");
assert_eq!(f.await, 92);
} This evaluation difference also shows up in other ways. You can't A |
Those are completely different pieces of code? The |
break vs return has already been discussed at length. Let's please not bikeshed this further unless new information comes to light. |
It does seem to me that interaction between async blocks and labeled blocks is novel information. This isn't covered in stabilization report. There is a bit of discussion here which culminates in
which update didn't seem to happen. Certainly, this wasn't discussed during break/return bikeshed which predates async blocks. Hence, my question of "did we actually thought about this properly, or is this design by accident?". I don't necessary want to re-open bikescheding here, but I do want to make sure our language design process is capable of noticing feature interactions and surfacing them as documented explicit decisions. I guess, one can say that these are two completely different snippets of code and there's no actual feature interactions here. But, as a naive user who doesn't look much beyond syntax, it sure does feel weird that we use "different" syntax to mean the "same" thing. |
It's not more weird than the fact that we have separate The However, I'm not sure whether there was much discussion of the differences between |
You're better thinking of
I think the important distinguisher is that block-break only works with a label. There's no (And if you attempt |
This seems to have landed without a documentation PR being open. Usually there should be documentation ready before the feature is stabilized. Was there something that I missed? The documentation checkbox was marked, but I don't see where that documentation was posted. Can someone please follow up on that? |
I don't agree, they are entirely orthogonal. However, you need to think of async blocks as "closures without arguments", or "thunks" in PL speak. A thunk is a suspended computation, i.e., a computation that can be continued later. Calling them async "blocks" is indeed confusing since it makes them sound like regular blocks, which they are not: fn main() {
let _x = { println!("hello from block") };
let _x = async { println!("hello from async block") };
} The 2nd println is never executed. Once you use an adequate mental model of async fn _f() {
let f = 'b: { break 'b 92 };
assert_eq!(f, 92);
}
fn _g() {
let f = || { return 92 };
assert_eq!(f(), 92);
}
More like
Your example is exactly like this one: fn uwu() -> i32 {
return 0;
}
fn foo() -> i32 { 'a: {
break 'a 0;
}} That's also "two different syntax to mean the same thing". |
# Stabilization proposal The feature was implemented in rust-lang/rust#50045 by est31 and has been in nightly since 2018-05-16 (over 4 years now). There are [no open issues][issue-label] other than the tracking issue. There is a strong consensus that `break` is the right keyword and we should not use `return`. 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). 1. nrc's original comment about cost-benefit analysis: rust-lang/rust#48594 (comment) 2. joshtriplett's comments about seeing use cases: rust-lang/rust#48594 (comment) 3. withoutboats's comments that Rust does not need more control flow constructs: rust-lang/rust#48594 (comment) Many different examples of code that's simpler using this feature have been provided: - A lexer by rpjohnst which must repeat code without label-break-value: rust-lang/rust#48594 (comment) - A snippet by SergioBenitez which avoids using a new function and adding several new return points to a function: rust-lang/rust#48594 (comment). This particular case would also work if `try` blocks were stabilized (at the cost of making the code harder to optimize). - Several examples by JohnBSmith: rust-lang/rust#48594 (comment) - Several examples by Centril: rust-lang/rust#48594 (comment) - An example by petrochenkov where this is used in the compiler itself to avoid duplicating error checking code: rust-lang/rust#48594 (comment) - Amanieu recently provided another example related to complex conditions, where try blocks would not have helped: rust-lang/rust#48594 (comment) 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: rust-lang/rust#48594 (comment) nrc later resolved their concern, mostly because of the aforementioned macro problems. joshtriplett suggested that macros could be able to generate IR directly (rust-lang/rust#48594 (comment)) but there are no open RFCs, and the design space seems rather speculative. joshtriplett later resolved his concerns, due to a symmetry between this feature and existing labelled break: rust-lang/rust#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: rust-lang/rust#48594 (comment) [issue-label]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AF-label_break_value+ ## Report + Feature gate: - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/src/test/ui/feature-gates/feature-gate-label_break_value.rs + Diagnostics: - https://github.com/rust-lang/rust/blob/da920d15830d2376be914c68767c4b7dca846959/compiler/rustc_parse/src/parser/diagnostics.rs#L2629 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L749 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L1001 - https://github.com/rust-lang/rust/blob/111df9e6eda1d752233482c1309d00d20a4bbf98/compiler/rustc_passes/src/loops.rs#L254 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L2079 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L1569 + Tests: - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_continue.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_unlabeled_break.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_illegal_uses.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/lint/unused_labels.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/run-pass/for-loop-while/label_break_value.rs ## Interactions with other features Labels follow the hygiene of local variables. label-break-value is permitted within `try` blocks: ```rust let _: Result<(), ()> = try { 'foo: { Err(())?; break 'foo; } }; ``` label-break-value is disallowed within closures, generators, and async blocks: ```rust 'a: { || break 'a //~^ ERROR use of unreachable label `'a` //~| ERROR `break` inside of a closure } ``` label-break-value is disallowed on [_BlockExpression_]; it can only occur as a [_LoopExpression_]: ```rust fn labeled_match() { match false 'b: { //~ ERROR block label not supported here _ => {} } } macro_rules! m { ($b:block) => { 'lab: $b; //~ ERROR cannot use a `block` macro fragment here unsafe $b; //~ ERROR cannot use a `block` macro fragment here |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here } } fn foo() { m!({}); } ``` [_BlockExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/block-expr.html [_LoopExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/loop-expr.html
…henkov Stabilize `#![feature(label_break_value)]` See the stabilization report in rust-lang/rust#48594 (comment).
# Stabilization proposal The feature was implemented in rust-lang/rust#50045 by est31 and has been in nightly since 2018-05-16 (over 4 years now). There are [no open issues][issue-label] other than the tracking issue. There is a strong consensus that `break` is the right keyword and we should not use `return`. 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). 1. nrc's original comment about cost-benefit analysis: rust-lang/rust#48594 (comment) 2. joshtriplett's comments about seeing use cases: rust-lang/rust#48594 (comment) 3. withoutboats's comments that Rust does not need more control flow constructs: rust-lang/rust#48594 (comment) Many different examples of code that's simpler using this feature have been provided: - A lexer by rpjohnst which must repeat code without label-break-value: rust-lang/rust#48594 (comment) - A snippet by SergioBenitez which avoids using a new function and adding several new return points to a function: rust-lang/rust#48594 (comment). This particular case would also work if `try` blocks were stabilized (at the cost of making the code harder to optimize). - Several examples by JohnBSmith: rust-lang/rust#48594 (comment) - Several examples by Centril: rust-lang/rust#48594 (comment) - An example by petrochenkov where this is used in the compiler itself to avoid duplicating error checking code: rust-lang/rust#48594 (comment) - Amanieu recently provided another example related to complex conditions, where try blocks would not have helped: rust-lang/rust#48594 (comment) 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: rust-lang/rust#48594 (comment) nrc later resolved their concern, mostly because of the aforementioned macro problems. joshtriplett suggested that macros could be able to generate IR directly (rust-lang/rust#48594 (comment)) but there are no open RFCs, and the design space seems rather speculative. joshtriplett later resolved his concerns, due to a symmetry between this feature and existing labelled break: rust-lang/rust#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: rust-lang/rust#48594 (comment) [issue-label]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AF-label_break_value+ ## Report + Feature gate: - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/src/test/ui/feature-gates/feature-gate-label_break_value.rs + Diagnostics: - https://github.com/rust-lang/rust/blob/6b2d3d5f3cd1e553d87b5496632132565b6779d3/compiler/rustc_parse/src/parser/diagnostics.rs#L2629 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L749 - https://github.com/rust-lang/rust/blob/f65bf0b2bb1a99f73095c01a118f3c37d3ee614c/compiler/rustc_resolve/src/diagnostics.rs#L1001 - https://github.com/rust-lang/rust/blob/111df9e6eda1d752233482c1309d00d20a4bbf98/compiler/rustc_passes/src/loops.rs#L254 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L2079 - https://github.com/rust-lang/rust/blob/d695a497bbf4b20d2580b75075faa80230d41667/compiler/rustc_parse/src/parser/expr.rs#L1569 + Tests: - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_continue.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_unlabeled_break.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/label/label_break_value_illegal_uses.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/lint/unused_labels.rs - https://github.com/rust-lang/rust/blob/master/src/test/ui/run-pass/for-loop-while/label_break_value.rs ## Interactions with other features Labels follow the hygiene of local variables. label-break-value is permitted within `try` blocks: ```rust let _: Result<(), ()> = try { 'foo: { Err(())?; break 'foo; } }; ``` label-break-value is disallowed within closures, generators, and async blocks: ```rust 'a: { || break 'a //~^ ERROR use of unreachable label `'a` //~| ERROR `break` inside of a closure } ``` label-break-value is disallowed on [_BlockExpression_]; it can only occur as a [_LoopExpression_]: ```rust fn labeled_match() { match false 'b: { //~ ERROR block label not supported here _ => {} } } macro_rules! m { ($b:block) => { 'lab: $b; //~ ERROR cannot use a `block` macro fragment here unsafe $b; //~ ERROR cannot use a `block` macro fragment here |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here } } fn foo() { m!({}); } ``` [_BlockExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/block-expr.html [_LoopExpression_]: https://doc.rust-lang.org/nightly/reference/expressions/loop-expr.html
…henkov Stabilize `#![feature(label_break_value)]` See the stabilization report in rust-lang/rust#48594 (comment).
This is a tracking issue for RFC 2046 (rust-lang/rfcs#2046).
Steps:
Unresolved questions:
return
as the keyword instead ofbreak
? RFC: label-break-value rfcs#2046 (comment)break
; call it resolved. Tracking issue for RFC 2046, label-break-value #48594 (comment)Note from shepard: This is a very long thread. If you're just looking for the 2022 conversation in which this ended up stabilized, jump to the report @ #48594 (comment)
The text was updated successfully, but these errors were encountered: