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

This commit is contained in:
Michael Goulet 2022-11-04 21:16:20 +00:00
parent c2a5c3a50f
commit 4e7fc663cc
3 changed files with 227 additions and 4 deletions

View File

@ -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");

View File

@ -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() {}

View File

@ -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