Skip to content

Commit 70ee7a6

Browse files
camelidGrigorenkoPV
authored andcommitted
Suggest adding missing braces in const block pattern
Previously it would only suggest wrapping the code in braces in regular expressions; now it does it in patterns too. This is a squashed rebase of #78173
1 parent 8de4c72 commit 70ee7a6

File tree

9 files changed

+38
-40
lines changed

9 files changed

+38
-40
lines changed

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,8 +1495,8 @@ impl<'a> Parser<'a> {
14951495
err
14961496
},
14971497
)
1498-
} else if this.check_inline_const(0) {
1499-
this.parse_const_block(lo, false)
1498+
} else if this.eat_keyword(exp!(Const)) {
1499+
this.parse_const_block(lo.to(this.prev_token.span), false)
15001500
} else if this.may_recover() && this.is_do_catch_block() {
15011501
this.recover_do_catch()
15021502
} else if this.is_try_block() {

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,9 +1281,8 @@ impl<'a> Parser<'a> {
12811281
}
12821282
}
12831283

1284-
/// Parses inline const expressions.
1284+
/// Parses inline const expressions. The `const` keyword was already eaten.
12851285
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
1286-
self.expect_keyword(exp!(Const))?;
12871286
let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
12881287
let anon_const = AnonConst {
12891288
id: DUMMY_NODE_ID,

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,9 @@ impl<'a> Parser<'a> {
779779
self.parse_pat_ident(BindingMode(ByRef::Yes(mutbl), Mutability::Not), syntax_loc)?
780780
} else if self.eat_keyword(exp!(Box)) {
781781
self.parse_pat_box()?
782-
} else if self.check_inline_const(0) {
783-
// Parse `const pat`
784-
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;
782+
} else if self.eat_keyword(exp!(Const)) {
783+
// Parse `const { pat }`
784+
let const_expr = self.parse_const_block(lo.to(self.prev_token.span), true)?;
785785

786786
if let Some(re) = self.parse_range_end() {
787787
self.parse_pat_range_begin_with(const_expr, re)?
@@ -1268,7 +1268,9 @@ impl<'a> Parser<'a> {
12681268
.then_some(self.prev_token.span);
12691269

12701270
let bound = if self.check_inline_const(0) {
1271-
self.parse_const_block(self.token.span, true)
1271+
let _eaten = self.eat_keyword(exp!(Const));
1272+
debug_assert!(_eaten);
1273+
self.parse_const_block(self.prev_token.span, true)
12721274
} else if self.check_path() {
12731275
let lo = self.token.span;
12741276
let (qself, path) = if self.eat_lt() {

compiler/rustc_parse/src/parser/stmt.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,15 +538,19 @@ impl<'a> Parser<'a> {
538538
//
539539
// the place-inside-a-block suggestion would be more likely wrong than right.
540540
//
541+
// But we don't want to trigger this if we just parsed a pattern,
542+
// so this only triggers if the current token is neither `=>` nor `=`.
543+
//
541544
// FIXME(compiler-errors): this should probably parse an arbitrary expr and not
542545
// just lookahead one token, so we can see if there's a brace after _that_,
543546
// since we want to protect against:
544547
// `if 1 1 + 1 {` being suggested as `if { 1 } 1 + 1 {`
545548
// + +
546549
Ok(Some(_))
547-
if (!self.token.is_keyword(kw::Else)
548-
&& self.look_ahead(1, |t| t == &token::OpenBrace))
549-
|| do_not_suggest_help => {}
550+
if do_not_suggest_help
551+
|| (self.token != token::FatArrow
552+
&& self.token != token::Eq
553+
&& self.look_ahead(1, |t| t == &token::OpenBrace)) => {}
550554
// Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836).
551555
Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {}
552556
Ok(Some(stmt)) => {

tests/ui/parser/bad-if-statements.stderr

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ note: the `if` expression is missing a block after this condition
6565
|
6666
LL | if true x else {}
6767
| ^^^^
68-
help: you might have meant to write this as part of a block
69-
|
70-
LL | if true { x } else {}
71-
| + +
7268

7369
error: this `if` expression is missing a block after the condition
7470
--> $DIR/bad-if-statements.rs:34:5

tests/ui/parser/block-no-opening-brace.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ fn in_async() {
3535

3636
// FIXME(#78168)
3737
fn in_const() {
38-
let x = const 2; //~ ERROR expected expression, found keyword `const`
38+
let x = const 2; //~ ERROR expected `{`, found `2`
3939
}
4040

4141
// FIXME(#78168)
4242
fn in_const_in_match() {
4343
let x = 2;
4444
match x {
4545
const 2 => {}
46-
//~^ ERROR expected identifier, found keyword `const`
47-
//~| ERROR expected one of `=>`, `if`, or `|`, found `2`
46+
//~^ ERROR expected `{`, found `2`
4847
}
4948
}

tests/ui/parser/block-no-opening-brace.stderr

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,27 @@ LL | async
5151
LL | let x = 0;
5252
| ^^^ unexpected token
5353

54-
error: expected expression, found keyword `const`
55-
--> $DIR/block-no-opening-brace.rs:38:13
54+
error: expected `{`, found `2`
55+
--> $DIR/block-no-opening-brace.rs:38:19
5656
|
5757
LL | let x = const 2;
58-
| ^^^^^ expected expression
59-
60-
error: expected identifier, found keyword `const`
61-
--> $DIR/block-no-opening-brace.rs:45:9
58+
| ^ expected `{`
6259
|
63-
LL | const 2 => {}
64-
| ^^^^^ expected identifier, found keyword
60+
help: you might have meant to write this as part of a block
61+
|
62+
LL | let x = const { 2 };
63+
| + +
6564

66-
error: expected one of `=>`, `if`, or `|`, found `2`
65+
error: expected `{`, found `2`
6766
--> $DIR/block-no-opening-brace.rs:45:15
6867
|
6968
LL | const 2 => {}
70-
| ^ expected one of `=>`, `if`, or `|`
69+
| ^ expected `{`
70+
|
71+
help: you might have meant to write this as part of a block
72+
|
73+
LL | const { 2 } => {}
74+
| + +
7175

72-
error: aborting due to 8 previous errors
76+
error: aborting due to 7 previous errors
7377

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// This file was auto-generated using 'src/etc/generate-keyword-tests.py const'
2-
31
fn main() {
4-
let const = "foo"; //~ error: expected identifier, found keyword `const`
2+
let const = "foo";
3+
//~^ ERROR expected `{`, found `=`
54
}
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
error: expected identifier, found keyword `const`
2-
--> $DIR/keyword-const-as-identifier.rs:4:9
1+
error: expected `{`, found `=`
2+
--> $DIR/keyword-const-as-identifier.rs:2:15
33
|
44
LL | let const = "foo";
5-
| ^^^^^ expected identifier, found keyword
6-
|
7-
help: escape `const` to use it as an identifier
8-
|
9-
LL | let r#const = "foo";
10-
| ++
5+
| ^ expected `{`
116

127
error: aborting due to 1 previous error
138

0 commit comments

Comments
 (0)