Skip to content

Commit 779886f

Browse files
committed
Improve recovery after unexpected tokens parsing sequence
1 parent a789fa0 commit 779886f

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,23 @@ impl<'a> Parser<'a> {
10331033
} else {
10341034
if let Err(e) = self.expect(t) {
10351035
fe(e);
1036-
break;
1036+
// Attempt to keep parsing if it was a similar separator
1037+
if let Some(ref tokens) = t.similar_tokens() {
1038+
if tokens.contains(&self.token) {
1039+
self.bump();
1040+
}
1041+
}
1042+
// Attempt to keep parsing if it was an omitted separator
1043+
match f(self) {
1044+
Ok(t) => {
1045+
v.push(t);
1046+
continue;
1047+
},
1048+
Err(mut e) => {
1049+
e.cancel();
1050+
break;
1051+
}
1052+
}
10371053
}
10381054
}
10391055
}

src/libsyntax/parse/token.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,16 @@ impl Token {
433433
})
434434
}
435435

436+
/// Returns tokens that are likely to be typed accidentally instead of the current token.
437+
/// Enables better error recovery when the wrong token is found.
438+
pub fn similar_tokens(&self) -> Option<Vec<Token>> {
439+
match *self {
440+
Comma => Some(vec![Dot, Lt]),
441+
Semi => Some(vec![Colon]),
442+
_ => None
443+
}
444+
}
445+
436446
/// Returns `true` if the token is either a special identifier or a keyword.
437447
pub fn is_reserved_ident(&self) -> bool {
438448
self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword()

0 commit comments

Comments
 (0)