Skip to content

Commit

Permalink
suggest a missing semicolon before an array
Browse files Browse the repository at this point in the history
  • Loading branch information
TaKO8Ki committed Aug 9, 2022
1 parent 6d3f1be commit 6d85bb9
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 0 deletions.
42 changes: 42 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1258,8 +1258,11 @@ impl<'a> Parser<'a> {

/// Parse an indexing expression `expr[...]`.
fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
let prev_span = self.prev_token.span;
let open_delim_span = self.token.span;
self.bump(); // `[`
let index = self.parse_expr()?;
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
self.expect(&token::CloseDelim(Delimiter::Bracket))?;
Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
}
Expand Down Expand Up @@ -2056,6 +2059,45 @@ impl<'a> Parser<'a> {
}
}

fn suggest_missing_semicolon_before_array(
&self,
prev_span: Span,
open_delim_span: Span,
) -> PResult<'a, ()> {
if self.token.kind == token::Comma {
let mut snapshot = self.create_snapshot_for_diagnostic();
snapshot.bump();
match snapshot.parse_seq_to_before_end(
&token::CloseDelim(Delimiter::Bracket),
SeqSep::trailing_allowed(token::Comma),
|p| p.parse_expr(),
) {
Ok(_)
// When the close delim is `)`, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
// but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
// This is because the `token.kind` of the close delim is treated as the same as
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
// Therefore, `token.kind` should not be compared here.
if snapshot
.span_to_snippet(snapshot.token.span)
.map_or(false, |snippet| snippet == "]") =>
{
let mut err = self.struct_span_err(open_delim_span, "expected `;`, found `[`");
err.span_suggestion_verbose(
prev_span.shrink_to_hi(),
"consider adding `;` here",
';',
Applicability::MaybeIncorrect,
);
return Err(err);
}
Ok(_) => (),
Err(err) => err.cancel(),
}
}
Ok(())
}

/// Parses a block or unsafe block.
pub(super) fn parse_block_expr(
&mut self,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn foo() {}

fn bar() -> [u8; 2] {
foo()
[1, 3) //~ ERROR expected one of `.`, `?`, `]`, or an operator, found `,`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: expected one of `.`, `?`, `]`, or an operator, found `,`
--> $DIR/do-not-suggest-suggest-semicolon-before-array.rs:5:5
|
LL | [1, 3)
| ^ ^ help: `]` may belong here
| |
| unclosed delimiter

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/parser/suggest-suggest-semicolon-before-array.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix
#![allow(dead_code)]

fn foo() {}

fn bar() -> [u8; 2] {
foo();
[1, 3] //~ ERROR expected `;`, found `[`
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/parser/suggest-suggest-semicolon-before-array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix
#![allow(dead_code)]

fn foo() {}

fn bar() -> [u8; 2] {
foo()
[1, 3] //~ ERROR expected `;`, found `[`
}

fn main() {}
13 changes: 13 additions & 0 deletions src/test/ui/parser/suggest-suggest-semicolon-before-array.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: expected `;`, found `[`
--> $DIR/suggest-suggest-semicolon-before-array.rs:8:5
|
LL | [1, 3]
| ^
|
help: consider adding `;` here
|
LL | foo();
| +

error: aborting due to previous error

0 comments on commit 6d85bb9

Please sign in to comment.