about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-08-18 16:35:19 +0200
committerMazdak Farrokhzad <twingoow@gmail.com>2019-08-24 21:32:48 +0200
commit30b841dce0a1c0f26588f4b5791a9eda1c1f42f4 (patch)
tree2fad54525e758c9a20d1f84281cf4274123f178f /src/libsyntax/parse/parser
parent0bbea47794d28f78cf313fde475a35a83d0e9842 (diff)
downloadrust-30b841dce0a1c0f26588f4b5791a9eda1c1f42f4.tar.gz
rust-30b841dce0a1c0f26588f4b5791a9eda1c1f42f4.zip
parser: improve or-patterns recovery.
Diffstat (limited to 'src/libsyntax/parse/parser')
-rw-r--r--src/libsyntax/parse/parser/pat.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index ca5a9f2a5a8..e52d0bc9d48 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -110,18 +110,25 @@ impl<'a> Parser<'a> {
 
         // If the next token is not a `|`,
         // this is not an or-pattern and we should exit here.
-        if !self.check(&token::BinOp(token::Or)) {
+        if !self.check(&token::BinOp(token::Or)) && self.token != token::OrOr {
             return Ok(first_pat)
         }
 
         let lo = first_pat.span;
-
         let mut pats = vec![first_pat];
+        loop {
+            if self.token == token::OrOr {
+                // Found `||`; Recover and pretend we parsed `|`.
+                self.ban_unexpected_or_or();
+                self.bump();
+            } else if self.eat(&token::BinOp(token::Or)) {
+                // Found `|`. Working towards a proper or-pattern.
+            } else {
+                break;
+            }
 
-        while self.eat(&token::BinOp(token::Or)) {
             pats.push(self.parse_pat_with_range_pat(true, expected)?);
         }
-
         let or_pattern_span = lo.to(self.prev_span);
 
         // Feature gate the or-pattern if instructed: