Rollup merge of #100334 - TaKO8Ki:suggest-missing-semicolon-before-array, r=fee1-dead

Suggest a missing semicolon before an array

fixes #99658
This commit is contained in:
Matthias Krüger 2022-08-10 07:21:37 +02:00 committed by GitHub
commit 354b831c32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 0 deletions

View File

@ -1258,8 +1258,11 @@ impl<'a> Parser<'a> {
/// Parse an indexing expression `expr[...]`. /// Parse an indexing expression `expr[...]`.
fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<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(); // `[` self.bump(); // `[`
let index = self.parse_expr()?; let index = self.parse_expr()?;
self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
self.expect(&token::CloseDelim(Delimiter::Bracket))?; self.expect(&token::CloseDelim(Delimiter::Bracket))?;
Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new())) Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
} }
@ -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. /// Parses a block or unsafe block.
pub(super) fn parse_block_expr( pub(super) fn parse_block_expr(
&mut self, &mut self,

View File

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

View File

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

View File

@ -0,0 +1,11 @@
// run-rustfix
#![allow(dead_code)]
fn foo() {}
fn bar() -> [u8; 2] {
foo();
[1, 3] //~ ERROR expected `;`, found `[`
}
fn main() {}

View File

@ -0,0 +1,11 @@
// run-rustfix
#![allow(dead_code)]
fn foo() {}
fn bar() -> [u8; 2] {
foo()
[1, 3] //~ ERROR expected `;`, found `[`
}
fn main() {}

View File

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