diff options
| author | bors <bors@rust-lang.org> | 2021-08-04 07:17:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-04 07:17:25 +0000 |
| commit | 49ca3d9796030fc0a85089460e9f825ceecc08ed (patch) | |
| tree | c2c0348ec5549e1e143498e37078e120e273fb6e /src | |
| parent | 71ff9b41e9ebd3e336019513917a7a8868d1cc66 (diff) | |
| parent | 7c81132a60579de56bd4baa7866fa9db2ecd5ddd (diff) | |
| download | rust-49ca3d9796030fc0a85089460e9f825ceecc08ed.tar.gz rust-49ca3d9796030fc0a85089460e9f825ceecc08ed.zip | |
Auto merge of #87026 - FabianWolff:issue-86948, r=estebank
Allow labeled loops as value expressions for `break`
Fixes #86948. This is currently allowed:
```rust
return 'label: loop { break 'label 42; };
break ('label: loop { break 'label 42; });
break 1 + 'label: loop { break 'label 42; };
break 'outer 'inner: loop { break 'inner 42; };
```
But not this:
```rust
break 'label: loop { break 'label 42; };
```
I have fixed this, so that the above now parses as an unlabeled break with a labeled loop as its value expression.
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/ui/parser/lifetime_starts_expressions.rs | 32 | ||||
| -rw-r--r-- | src/test/ui/parser/lifetime_starts_expressions.stderr | 52 |
2 files changed, 67 insertions, 17 deletions
diff --git a/src/test/ui/parser/lifetime_starts_expressions.rs b/src/test/ui/parser/lifetime_starts_expressions.rs index e0098793e1f..903b4de6ef4 100644 --- a/src/test/ui/parser/lifetime_starts_expressions.rs +++ b/src/test/ui/parser/lifetime_starts_expressions.rs @@ -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; + }; + }; } diff --git a/src/test/ui/parser/lifetime_starts_expressions.stderr b/src/test/ui/parser/lifetime_starts_expressions.stderr index 7275841ebb8..6f3320e283c 100644 --- a/src/test/ui/parser/lifetime_starts_expressions.stderr +++ b/src/test/ui/parser/lifetime_starts_expressions.stderr @@ -1,23 +1,47 @@ -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 | }); + | + +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; }; + | |______________________________^ + | + = note: `#[warn(break_with_label_and_loop)]` on by default +help: wrap this expression in parentheses | - = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` +LL | (loop { break 42; }); + | ^ ^ -error: aborting due to 2 previous errors +error: aborting due to 2 previous errors; 1 warning emitted |
