Skip to content

Commit 354b831

Browse files
authored
Rollup merge of #100334 - TaKO8Ki:suggest-missing-semicolon-before-array, r=fee1-dead
Suggest a missing semicolon before an array fixes #99658
2 parents 0cbecda + 6d85bb9 commit 354b831

6 files changed

+95
-0
lines changed

compiler/rustc_parse/src/parser/expr.rs

+42
Original file line numberDiff line numberDiff line change
@@ -1258,8 +1258,11 @@ impl<'a> Parser<'a> {
12581258

12591259
/// Parse an indexing expression `expr[...]`.
12601260
fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
1261+
let prev_span = self.prev_token.span;
1262+
let open_delim_span = self.token.span;
12611263
self.bump(); // `[`
12621264
let index = self.parse_expr()?;
1265+
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
12631266
self.expect(&token::CloseDelim(Delimiter::Bracket))?;
12641267
Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
12651268
}
@@ -2056,6 +2059,45 @@ impl<'a> Parser<'a> {
20562059
}
20572060
}
20582061

2062+
fn suggest_missing_semicolon_before_array(
2063+
&self,
2064+
prev_span: Span,
2065+
open_delim_span: Span,
2066+
) -> PResult<'a, ()> {
2067+
if self.token.kind == token::Comma {
2068+
let mut snapshot = self.create_snapshot_for_diagnostic();
2069+
snapshot.bump();
2070+
match snapshot.parse_seq_to_before_end(
2071+
&token::CloseDelim(Delimiter::Bracket),
2072+
SeqSep::trailing_allowed(token::Comma),
2073+
|p| p.parse_expr(),
2074+
) {
2075+
Ok(_)
2076+
// When the close delim is `)`, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
2077+
// but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
2078+
// This is because the `token.kind` of the close delim is treated as the same as
2079+
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
2080+
// Therefore, `token.kind` should not be compared here.
2081+
if snapshot
2082+
.span_to_snippet(snapshot.token.span)
2083+
.map_or(false, |snippet| snippet == "]") =>
2084+
{
2085+
let mut err = self.struct_span_err(open_delim_span, "expected `;`, found `[`");
2086+
err.span_suggestion_verbose(
2087+
prev_span.shrink_to_hi(),
2088+
"consider adding `;` here",
2089+
';',
2090+
Applicability::MaybeIncorrect,
2091+
);
2092+
return Err(err);
2093+
}
2094+
Ok(_) => (),
2095+
Err(err) => err.cancel(),
2096+
}
2097+
}
2098+
Ok(())
2099+
}
2100+
20592101
/// Parses a block or unsafe block.
20602102
pub(super) fn parse_block_expr(
20612103
&mut self,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn foo() {}
2+
3+
fn bar() -> [u8; 2] {
4+
foo()
5+
[1, 3) //~ ERROR expected one of `.`, `?`, `]`, or an operator, found `,`
6+
}
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: expected one of `.`, `?`, `]`, or an operator, found `,`
2+
--> $DIR/do-not-suggest-suggest-semicolon-before-array.rs:5:5
3+
|
4+
LL | [1, 3)
5+
| ^ ^ help: `]` may belong here
6+
| |
7+
| unclosed delimiter
8+
9+
error: aborting due to previous error
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
4+
fn foo() {}
5+
6+
fn bar() -> [u8; 2] {
7+
foo();
8+
[1, 3] //~ ERROR expected `;`, found `[`
9+
}
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
4+
fn foo() {}
5+
6+
fn bar() -> [u8; 2] {
7+
foo()
8+
[1, 3] //~ ERROR expected `;`, found `[`
9+
}
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: expected `;`, found `[`
2+
--> $DIR/suggest-suggest-semicolon-before-array.rs:8:5
3+
|
4+
LL | [1, 3]
5+
| ^
6+
|
7+
help: consider adding `;` here
8+
|
9+
LL | foo();
10+
| +
11+
12+
error: aborting due to previous error
13+

0 commit comments

Comments
 (0)