Skip to content

Commit af4acd0

Browse files
authored
Rollup merge of rust-lang#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 `()` ```
2 parents ca9f04e + 9b6b3d6 commit af4acd0

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/libsyntax/parse/parser.rs

+26
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,34 @@ impl<'a> Parser<'a> {
851851
}
852852
}
853853

854+
let is_semi_suggestable = expected.iter().any(|t| match t {
855+
TokenType::Token(token::Semi) => true, // we expect a `;` here
856+
_ => false,
857+
}) && ( // a `;` would be expected before the current keyword
858+
self.token.is_keyword(keywords::Break) ||
859+
self.token.is_keyword(keywords::Continue) ||
860+
self.token.is_keyword(keywords::For) ||
861+
self.token.is_keyword(keywords::If) ||
862+
self.token.is_keyword(keywords::Let) ||
863+
self.token.is_keyword(keywords::Loop) ||
864+
self.token.is_keyword(keywords::Match) ||
865+
self.token.is_keyword(keywords::Return) ||
866+
self.token.is_keyword(keywords::While)
867+
);
854868
let cm = self.sess.source_map();
855869
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
870+
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
871+
// The spans are in different lines, expected `;` and found `let` or `return`.
872+
// High likelihood that it is only a missing `;`.
873+
err.span_suggestion_short(
874+
label_sp,
875+
"a semicolon may be missing here",
876+
";".to_string(),
877+
Applicability::MaybeIncorrect,
878+
);
879+
err.emit();
880+
return Ok(true);
881+
}
856882
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
857883
// When the spans are in the same line, it means that the only content between
858884
// them is whitespace, point at the found token in that case:
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
let _: usize = ()
3+
//~^ ERROR mismatched types
4+
let _ = 3;
5+
//~^ ERROR expected one of
6+
}
7+
8+
fn foo() -> usize {
9+
let _: usize = ()
10+
//~^ ERROR mismatched types
11+
return 3;
12+
//~^ ERROR expected one of
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error: expected one of `.`, `;`, `?`, or an operator, found `let`
2+
--> $DIR/recover-missing-semi.rs:4:5
3+
|
4+
LL | let _: usize = ()
5+
| - help: a semicolon may be missing here
6+
LL |
7+
LL | let _ = 3;
8+
| ^^^
9+
10+
error: expected one of `.`, `;`, `?`, or an operator, found `return`
11+
--> $DIR/recover-missing-semi.rs:11:5
12+
|
13+
LL | let _: usize = ()
14+
| - help: a semicolon may be missing here
15+
LL |
16+
LL | return 3;
17+
| ^^^^^^
18+
19+
error[E0308]: mismatched types
20+
--> $DIR/recover-missing-semi.rs:2:20
21+
|
22+
LL | let _: usize = ()
23+
| ^^ expected usize, found ()
24+
|
25+
= note: expected type `usize`
26+
found type `()`
27+
28+
error[E0308]: mismatched types
29+
--> $DIR/recover-missing-semi.rs:9:20
30+
|
31+
LL | let _: usize = ()
32+
| ^^ expected usize, found ()
33+
|
34+
= note: expected type `usize`
35+
found type `()`
36+
37+
error: aborting due to 4 previous errors
38+
39+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)