Require parentheses to avoid confusions around labeled break and loop expressions

This commit is contained in:
Fabian Wolff 2021-07-10 16:38:55 +02:00
parent 7069a8c2b7
commit 470cbc0e2e
6 changed files with 152 additions and 21 deletions

View file

@ -1,13 +1,39 @@
#![allow(unused, dead_code)]
fn foo() -> u32 {
return 'label: loop { break 'label 42; };
}
fn bar() -> u32 {
loop { break 'label: loop { break 'label 42; }; }
//~^ ERROR expected identifier, found keyword `loop`
//~| ERROR expected type, found keyword `loop`
//~^ ERROR: parentheses are required around this expression to avoid confusion
//~| HELP: wrap the expression in parentheses
}
fn baz() -> u32 {
'label: loop {
break 'label
//~^ WARNING: this labeled break expression is easy to confuse with an unlabeled break
loop { break 42; };
//~^ HELP: wrap this expression in parentheses
};
'label2: loop {
break 'label2 'inner: loop { break 42; };
// no warnings or errors here
}
}
pub fn main() {
foo();
// Regression test for issue #86948, as resolved in #87026:
let a = 'first_loop: loop {
break 'first_loop 1;
};
let b = loop {
break 'inner_loop: loop {
//~^ ERROR: parentheses are required around this expression to avoid confusion
//~| HELP: wrap the expression in parentheses
break 'inner_loop 1;
};
};
}

View file

@ -1,23 +1,45 @@
error: expected identifier, found keyword `loop`
--> $DIR/lifetime_starts_expressions.rs:6:26
error: parentheses are required around this expression to avoid confusion with a labeled break expression
--> $DIR/lifetime_starts_expressions.rs:8:18
|
LL | loop { break 'label: loop { break 'label 42; }; }
| ^^^^ expected identifier, found keyword
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: you can escape reserved keywords to use them as identifiers
help: wrap the expression in parentheses
|
LL | loop { break 'label: r#loop { break 'label 42; }; }
| ^^^^^^
LL | loop { break ('label: loop { break 'label 42; }); }
| ^ ^
error: expected type, found keyword `loop`
--> $DIR/lifetime_starts_expressions.rs:6:26
error: parentheses are required around this expression to avoid confusion with a labeled break expression
--> $DIR/lifetime_starts_expressions.rs:33:15
|
LL | loop { break 'label: loop { break 'label 42; }; }
| - ^^^^ expected type
| |
| help: maybe write a path separator here: `::`
LL | break 'inner_loop: loop {
| _______________^
LL | |
LL | |
LL | | break 'inner_loop 1;
LL | | };
| |_________^
|
help: wrap the expression in parentheses
|
LL | break ('inner_loop: loop {
LL |
LL |
LL | break 'inner_loop 1;
LL | });
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
error: aborting due to 2 previous errors
warning: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
--> $DIR/lifetime_starts_expressions.rs:15:9
|
LL | / break 'label
LL | |
LL | | loop { break 42; };
| |_____________-----------------^
| |
| help: wrap this expression in parentheses: `(loop { break 42; })`
|
= note: `#[warn(break_with_label_and_loop)]` on by default
error: aborting due to 2 previous errors; 1 warning emitted