about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-10-28 03:02:17 +0000
committerbors <bors@rust-lang.org>2017-10-28 03:02:17 +0000
commitc1a0b6d9eb888ded9a7204db0d67d62b1cdc9944 (patch)
tree0e5481df011f16a6a64164344cdd089227f6dab6 /src/libsyntax
parentd9f124965551e8fb9403def6a715e13dfd5e9c95 (diff)
parentae6a9e6fd2a7138d04c03e2a30458d7ebcc68627 (diff)
downloadrust-c1a0b6d9eb888ded9a7204db0d67d62b1cdc9944.tar.gz
rust-c1a0b6d9eb888ded9a7204db0d67d62b1cdc9944.zip
Auto merge of #45503 - thombles:tk/i44339-v5, r=petrochenkov
Improve diagnostics when list of tokens has incorrect separators

Make `parse_seq_to_before_tokens` more resilient to error conditions. Where possible it is better if it can consume up to the final bracket before returning. This change improves the diagnostics in a couple of situations:

```
struct S(pub () ()); // omitted separator
use std::{foo. bar}; // used a similar but wrong separator
```

Fixes #44339
r? @petrochenkov
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/parse/parser.rs18
-rw-r--r--src/libsyntax/parse/token.rs10
2 files changed, 27 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a2c431dc8b1..e96a5417aff 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()