Rollup merge of #59866 - estebank:recover-missing-semi, r=petrochenkov
Recover from missing semicolon based on the found token When encountering one of a few keywords when a semicolon was expected, suggest the semicolon and recover: ``` error: expected one of `.`, `;`, `?`, or an operator, found `let` --> $DIR/recover-missing-semi.rs:4:5 | LL | let _: usize = () | - help: missing semicolon here LL | LL | let _ = 3; | ^^^ error[E0308]: mismatched types --> $DIR/recover-missing-semi.rs:2:20 | LL | let _: usize = () | ^^ expected usize, found () | = note: expected type `usize` found type `()` ```
This commit is contained in:
commit
af4acd0533
@ -851,8 +851,34 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let is_semi_suggestable = expected.iter().any(|t| match t {
|
||||
TokenType::Token(token::Semi) => true, // we expect a `;` here
|
||||
_ => false,
|
||||
}) && ( // a `;` would be expected before the current keyword
|
||||
self.token.is_keyword(keywords::Break) ||
|
||||
self.token.is_keyword(keywords::Continue) ||
|
||||
self.token.is_keyword(keywords::For) ||
|
||||
self.token.is_keyword(keywords::If) ||
|
||||
self.token.is_keyword(keywords::Let) ||
|
||||
self.token.is_keyword(keywords::Loop) ||
|
||||
self.token.is_keyword(keywords::Match) ||
|
||||
self.token.is_keyword(keywords::Return) ||
|
||||
self.token.is_keyword(keywords::While)
|
||||
);
|
||||
let cm = self.sess.source_map();
|
||||
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
|
||||
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
|
||||
// The spans are in different lines, expected `;` and found `let` or `return`.
|
||||
// High likelihood that it is only a missing `;`.
|
||||
err.span_suggestion_short(
|
||||
label_sp,
|
||||
"a semicolon may be missing here",
|
||||
";".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.emit();
|
||||
return Ok(true);
|
||||
}
|
||||
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
|
||||
// When the spans are in the same line, it means that the only content between
|
||||
// them is whitespace, point at the found token in that case:
|
||||
|
13
src/test/ui/parser/recover-missing-semi.rs
Normal file
13
src/test/ui/parser/recover-missing-semi.rs
Normal file
@ -0,0 +1,13 @@
|
||||
fn main() {
|
||||
let _: usize = ()
|
||||
//~^ ERROR mismatched types
|
||||
let _ = 3;
|
||||
//~^ ERROR expected one of
|
||||
}
|
||||
|
||||
fn foo() -> usize {
|
||||
let _: usize = ()
|
||||
//~^ ERROR mismatched types
|
||||
return 3;
|
||||
//~^ ERROR expected one of
|
||||
}
|
39
src/test/ui/parser/recover-missing-semi.stderr
Normal file
39
src/test/ui/parser/recover-missing-semi.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error: expected one of `.`, `;`, `?`, or an operator, found `let`
|
||||
--> $DIR/recover-missing-semi.rs:4:5
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| - help: a semicolon may be missing here
|
||||
LL |
|
||||
LL | let _ = 3;
|
||||
| ^^^
|
||||
|
||||
error: expected one of `.`, `;`, `?`, or an operator, found `return`
|
||||
--> $DIR/recover-missing-semi.rs:11:5
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| - help: a semicolon may be missing here
|
||||
LL |
|
||||
LL | return 3;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-missing-semi.rs:2:20
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| ^^ expected usize, found ()
|
||||
|
|
||||
= note: expected type `usize`
|
||||
found type `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-missing-semi.rs:9:20
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| ^^ expected usize, found ()
|
||||
|
|
||||
= note: expected type `usize`
|
||||
found type `()`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user