Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest adding missing braces in const block pattern #130751

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1472,7 +1472,7 @@ impl<'a> Parser<'a> {
err
},
)
} else if this.check_inline_const(0) {
} else if this.check_keyword(kw::Const) {
this.parse_const_block(lo.to(this.token.span), false)
} else if this.may_recover() && this.is_do_catch_block() {
this.recover_do_catch()
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,8 @@ impl<'a> Parser<'a> {
self.parse_pat_ident(BindingMode(ByRef::Yes(mutbl), Mutability::Not), syntax_loc)?
} else if self.eat_keyword(kw::Box) {
self.parse_pat_box()?
} else if self.check_inline_const(0) {
// Parse `const pat`
} else if self.check_keyword(kw::Const) {
// Parse `const { pat }`
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;

if let Some(re) = self.parse_range_end() {
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,21 @@ impl<'a> Parser<'a> {
//
// the place-inside-a-block suggestion would be more likely wrong than right.
//
// But we don't want to trigger this if we just parsed a pattern,
// so this only triggers if the current token is neither `=>` nor `=`.
//
// FIXME(compiler-errors): this should probably parse an arbitrary expr and not
// just lookahead one token, so we can see if there's a brace after _that_,
// since we want to protect against:
// `if 1 1 + 1 {` being suggested as `if { 1 } 1 + 1 {`
// + +
Ok(Some(_))
if (!self.token.is_keyword(kw::Else)
&& self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)))
|| do_not_suggest_help => {}
if do_not_suggest_help
|| (self.token != token::FatArrow
&& self.token != token::Eq
&& self.look_ahead(1, |t| {
t == &token::OpenDelim(token::Delimiter::Brace)
})) => {}
// Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836).
Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {}
Ok(Some(stmt)) => {
Expand All @@ -520,7 +526,7 @@ impl<'a> Parser<'a> {
(stmt_span.shrink_to_lo(), "{ ".to_string()),
(stmt_span.shrink_to_hi(), " }".to_string()),
],
// Speculative; has been misleading in the past (#46836).
// Speculative; has been misleading in the past (see #46836).
Applicability::MaybeIncorrect,
);
}
Expand Down
4 changes: 0 additions & 4 deletions tests/ui/parser/bad-if-statements.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ note: the `if` expression is missing a block after this condition
|
LL | if true x else {}
| ^^^^
help: try placing this code inside a block
|
LL | if true { x } else {}
| + +

error: this `if` expression is missing a block after the condition
--> $DIR/bad-if-statements.rs:34:5
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/parser/block-no-opening-brace.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ edition:2018

#![feature(try_blocks)]
#![feature(try_blocks, inline_const_pat)]

fn main() {}

Expand Down Expand Up @@ -35,15 +35,14 @@ fn in_async() {

// FIXME(#78168)
fn in_const() {
let x = const 2; //~ ERROR expected expression, found keyword `const`
let x = const 2; //~ ERROR expected `{`, found `2`
}

// FIXME(#78168)
fn in_const_in_match() {
let x = 2;
match x {
const 2 => {}
//~^ ERROR expected identifier, found keyword `const`
//~| ERROR expected one of `=>`, `if`, or `|`, found `2`
//~^ ERROR expected `{`, found `2`
}
}
26 changes: 15 additions & 11 deletions tests/ui/parser/block-no-opening-brace.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,27 @@ LL | async
LL | let x = 0;
| ^^^ unexpected token

error: expected expression, found keyword `const`
--> $DIR/block-no-opening-brace.rs:38:13
error: expected `{`, found `2`
--> $DIR/block-no-opening-brace.rs:38:19
|
LL | let x = const 2;
| ^^^^^ expected expression

error: expected identifier, found keyword `const`
--> $DIR/block-no-opening-brace.rs:45:9
| ^ expected `{`
|
LL | const 2 => {}
| ^^^^^ expected identifier, found keyword
help: try placing this code inside a block
|
LL | let x = const { 2 };
| + +

error: expected one of `=>`, `if`, or `|`, found `2`
error: expected `{`, found `2`
--> $DIR/block-no-opening-brace.rs:45:15
|
LL | const 2 => {}
| ^ expected one of `=>`, `if`, or `|`
| ^ expected `{`
|
help: try placing this code inside a block
|
LL | const { 2 } => {}
| + +

error: aborting due to 8 previous errors
error: aborting due to 7 previous errors

29 changes: 29 additions & 0 deletions tests/ui/parser/inline-const-pat-let.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//@ run-pass

#![feature(inline_const_pat)]

fn if_let_1() -> i32 {
let x = 2;
const Y: i32 = 3;

if let const { (Y + 1) / 2 } = x {
x
} else {
0
}
}

fn if_let_2() -> i32 {
let x = 2;

if let const { 1 + 2 } = x {
const { 1 + 2 }
} else {
0
}
}

fn main() {
assert_eq!(if_let_1(), 2);
assert_eq!(if_let_2(), 0);
}
60 changes: 60 additions & 0 deletions tests/ui/parser/inline-const-without-block.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//@ run-rustfix

// See issue #78168.

#![feature(inline_const_pat)]

// FIXME(#78171): the lint has to be allowed because of a bug
#[allow(dead_code)]
const fn one() -> i32 {
1
}

fn foo() -> i32 {
let x = 2;

match x {
const { 2 } => {}
//~^ ERROR expected `{`, found `2`
//~| HELP try placing this code inside a block
_ => {}
}

match x {
const { 1 + 2 * 3 / 4 } => {}
//~^ ERROR expected `{`, found `1`
//~| HELP try placing this code inside a block
_ => {}
}

match x {
const { one() } => {}
//~^ ERROR expected `{`, found `one`
//~| HELP try placing this code inside a block
_ => {}
}

x
}

fn bar() -> i32 {
let x = const { 2 };
//~^ ERROR expected `{`, found `2`
//~| HELP try placing this code inside a block

x
}

fn baz() -> i32 {
let y = const { 1 + 2 * 3 / 4 };
//~^ ERROR expected `{`, found `1`
//~| HELP try placing this code inside a block

y
}

fn main() {
foo();
bar();
baz();
}
60 changes: 60 additions & 0 deletions tests/ui/parser/inline-const-without-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//@ run-rustfix

// See issue #78168.

#![feature(inline_const_pat)]

// FIXME(#78171): the lint has to be allowed because of a bug
#[allow(dead_code)]
const fn one() -> i32 {
1
}

fn foo() -> i32 {
let x = 2;

match x {
const 2 => {}
//~^ ERROR expected `{`, found `2`
//~| HELP try placing this code inside a block
_ => {}
}

match x {
const 1 + 2 * 3 / 4 => {}
//~^ ERROR expected `{`, found `1`
//~| HELP try placing this code inside a block
_ => {}
}

match x {
const one() => {}
//~^ ERROR expected `{`, found `one`
//~| HELP try placing this code inside a block
_ => {}
}

x
}

fn bar() -> i32 {
let x = const 2;
//~^ ERROR expected `{`, found `2`
//~| HELP try placing this code inside a block

x
}

fn baz() -> i32 {
let y = const 1 + 2 * 3 / 4;
//~^ ERROR expected `{`, found `1`
//~| HELP try placing this code inside a block

y
}

fn main() {
foo();
bar();
baz();
}
57 changes: 57 additions & 0 deletions tests/ui/parser/inline-const-without-block.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
error: expected `{`, found `2`
--> $DIR/inline-const-without-block.rs:17:15
|
LL | const 2 => {}
| ^ expected `{`
|
help: try placing this code inside a block
|
LL | const { 2 } => {}
| + +

error: expected `{`, found `1`
--> $DIR/inline-const-without-block.rs:24:15
|
LL | const 1 + 2 * 3 / 4 => {}
| ^ expected `{`
|
help: try placing this code inside a block
|
LL | const { 1 + 2 * 3 / 4 } => {}
| + +

error: expected `{`, found `one`
--> $DIR/inline-const-without-block.rs:31:15
|
LL | const one() => {}
| ^^^ expected `{`
|
help: try placing this code inside a block
|
LL | const { one() } => {}
| + +

error: expected `{`, found `2`
--> $DIR/inline-const-without-block.rs:41:19
|
LL | let x = const 2;
| ^ expected `{`
|
help: try placing this code inside a block
|
LL | let x = const { 2 };
| + +

error: expected `{`, found `1`
--> $DIR/inline-const-without-block.rs:49:19
|
LL | let y = const 1 + 2 * 3 / 4;
| ^ expected `{`
|
help: try placing this code inside a block
|
LL | let y = const { 1 + 2 * 3 / 4 };
| + +

error: aborting due to 5 previous errors

6 changes: 3 additions & 3 deletions tests/ui/parser/keyword-const-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py const'

fn main() {
let const = "foo"; //~ error: expected identifier, found keyword `const`
let const = "foo";
//~^ ERROR expected `{`, found `=`
//~| ERROR inline-const in pattern position is experimental [E0658]
}
20 changes: 13 additions & 7 deletions tests/ui/parser/keyword-const-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
error: expected identifier, found keyword `const`
--> $DIR/keyword-const-as-identifier.rs:4:9
error: expected `{`, found `=`
--> $DIR/keyword-const-as-identifier.rs:2:15
|
LL | let const = "foo";
| ^^^^^ expected identifier, found keyword
| ^ expected `{`

error[E0658]: inline-const in pattern position is experimental
--> $DIR/keyword-const-as-identifier.rs:2:9
|
help: escape `const` to use it as an identifier
LL | let const = "foo";
| ^^^^^
|
LL | let r#const = "foo";
| ++
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 1 previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
Loading