diff options
| author | Thomas Karpiniec <tk@1.21jiggawatts.net> | 2017-10-25 00:04:01 +1100 |
|---|---|---|
| committer | Thomas Karpiniec <tk@1.21jiggawatts.net> | 2017-10-25 00:04:01 +1100 |
| commit | 779886f1825c49ec880c9f79f1dd8d488dc0caf0 (patch) | |
| tree | 3fb966d4f9d37ce488e38d561b267dc7068cb321 | |
| parent | a789fa0440214347e1bf6228fdb8fd36bf2f4520 (diff) | |
| download | rust-779886f1825c49ec880c9f79f1dd8d488dc0caf0.tar.gz rust-779886f1825c49ec880c9f79f1dd8d488dc0caf0.zip | |
Improve recovery after unexpected tokens parsing sequence
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 10 |
2 files changed, 27 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 07fa2a4d1a7..cf56be25665 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1033,7 +1033,23 @@ impl<'a> Parser<'a> { } else { if let Err(e) = self.expect(t) { fe(e); - break; + // Attempt to keep parsing if it was a similar separator + if let Some(ref tokens) = t.similar_tokens() { + if tokens.contains(&self.token) { + self.bump(); + } + } + // Attempt to keep parsing if it was an omitted separator + match f(self) { + Ok(t) => { + v.push(t); + continue; + }, + Err(mut e) => { + e.cancel(); + break; + } + } } } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 20db87cfc82..09dc05a4167 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -433,6 +433,16 @@ impl Token { }) } + /// Returns tokens that are likely to be typed accidentally instead of the current token. + /// Enables better error recovery when the wrong token is found. + pub fn similar_tokens(&self) -> Option<Vec<Token>> { + match *self { + Comma => Some(vec![Dot, Lt]), + Semi => Some(vec![Colon]), + _ => None + } + } + /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved_ident(&self) -> bool { self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword() |
