Skip to content

Commit

Permalink
Rollup merge of rust-lang#103986 - compiler-errors:oh-no-bad-block-sh…
Browse files Browse the repository at this point in the history
…ould-not-have-label, r=lcnr

Don't silently eat label before block in block-like expr

Fixes rust-lang#103983
cc rust-lang#92823 (where the regression was introduced)
  • Loading branch information
Dylan-DPC authored Nov 7, 2022
2 parents 408b8cf + 4e7fc66 commit 170ad4a
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 4 deletions.
12 changes: 8 additions & 4 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2468,11 +2468,15 @@ impl<'a> Parser<'a> {
}

pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool {
let Some(label) = self.eat_label().filter(|_| {
self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace)
}) else {
// Check for `'a : {`
if !(self.check_lifetime()
&& self.look_ahead(1, |tok| tok.kind == token::Colon)
&& self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Brace)))
{
return false;
};
}
let label = self.eat_label().expect("just checked if a label exists");
self.bump(); // eat `:`
let span = label.ident.span.to(self.prev_token.span);
let mut err = self.struct_span_err(span, "block label not supported here");
err.span_label(span, "not supported here");
Expand Down
43 changes: 43 additions & 0 deletions src/test/ui/parser/label-after-block-like.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
fn a() {
if let () = () 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn b() {
if true 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn c() {
loop 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn d() {
while true 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn e() {
while let () = () 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn f() {
for _ in 0..0 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn g() {
unsafe 'a {}
//~^ ERROR labeled expression must be followed by `:`
//~| ERROR expected `{`, found `'a`
}

fn main() {}
176 changes: 176 additions & 0 deletions src/test/ui/parser/label-after-block-like.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:2:20
|
LL | if let () = () 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:2:20
|
LL | if let () = () 'a {}
| ^^ expected `{`
|
note: the `if` expression is missing a block after this condition
--> $DIR/label-after-block-like.rs:2:8
|
LL | if let () = () 'a {}
| ^^^^^^^^^^^
help: try placing this code inside a block
|
LL | if let () = () { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:8:13
|
LL | if true 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:8:13
|
LL | if true 'a {}
| ^^ expected `{`
|
note: the `if` expression is missing a block after this condition
--> $DIR/label-after-block-like.rs:8:8
|
LL | if true 'a {}
| ^^^^
help: try placing this code inside a block
|
LL | if true { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:14:10
|
LL | loop 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:14:10
|
LL | loop 'a {}
| ---- ^^ expected `{`
| |
| while parsing this `loop` expression
|
help: try placing this code inside a block
|
LL | loop { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:20:16
|
LL | while true 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:20:16
|
LL | while true 'a {}
| ----- ---- ^^ expected `{`
| | |
| | this `while` condition successfully parsed
| while parsing the body of this `while` expression
|
help: try placing this code inside a block
|
LL | while true { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:26:23
|
LL | while let () = () 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:26:23
|
LL | while let () = () 'a {}
| ----- ----------- ^^ expected `{`
| | |
| | this `while` condition successfully parsed
| while parsing the body of this `while` expression
|
help: try placing this code inside a block
|
LL | while let () = () { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:32:19
|
LL | for _ in 0..0 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:32:19
|
LL | for _ in 0..0 'a {}
| ^^ expected `{`
|
help: try placing this code inside a block
|
LL | for _ in 0..0 { 'a {} }
| + +

error: labeled expression must be followed by `:`
--> $DIR/label-after-block-like.rs:38:12
|
LL | unsafe 'a {}
| ---^^
| | |
| | help: add `:` after the label
| the label
|
= note: labels are used before loops and blocks, allowing e.g., `break 'label` to them

error: expected `{`, found `'a`
--> $DIR/label-after-block-like.rs:38:12
|
LL | unsafe 'a {}
| ------ ^^ expected `{`
| |
| while parsing this `unsafe` expression
|
help: try placing this code inside a block
|
LL | unsafe { 'a {} }
| + +

error: aborting due to 14 previous errors

0 comments on commit 170ad4a

Please sign in to comment.