about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-03-28 19:58:45 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-03-28 19:58:45 -0700
commit9ea6790a6444fbf65d0cba9c9518abf70077f3de (patch)
tree09cd3326892317af525123875fe84f77b6065201 /src/libsyntax/parse
parentb7dc8e71ccb15ff54b9cdf0f67776cc3cf4bea33 (diff)
downloadrust-9ea6790a6444fbf65d0cba9c9518abf70077f3de.tar.gz
rust-9ea6790a6444fbf65d0cba9c9518abf70077f3de.zip
Deduplicate parse recovery code
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs78
1 files changed, 43 insertions, 35 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ea0c7e0e366..d4b8c7ce159 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2639,11 +2639,9 @@ impl<'a> Parser<'a> {
                 while self.token != token::CloseDelim(token::Paren) {
                     es.push(match self.parse_expr() {
                         Ok(es) => es,
-                        Err(mut err) => {  // recover from parse error in tuple list
-                            err.emit();
-                            self.consume_block(token::Paren);
-                            hi = self.prev_span;
-                            return Ok(self.mk_expr(lo.to(hi), ExprKind::Err, ThinVec::new()));
+                        Err(err) => {
+                            // recover from parse error in tuple list
+                            return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err)));
                         }
                     });
                     recovered = self.expect_one_of(
@@ -3254,44 +3252,54 @@ impl<'a> Parser<'a> {
             }
             if self.expr_is_complete(&e) { break; }
             match self.token {
-              // expr(...)
-              token::OpenDelim(token::Paren) => {
-                match self.parse_unspanned_seq(
-                    &token::OpenDelim(token::Paren),
-                    &token::CloseDelim(token::Paren),
-                    SeqSep::trailing_allowed(token::Comma),
-                    |p| Ok(p.parse_expr()?)
-                ) {
-                    Ok(es) => {
+                // expr(...)
+                token::OpenDelim(token::Paren) => {
+                    let seq = self.parse_unspanned_seq(
+                        &token::OpenDelim(token::Paren),
+                        &token::CloseDelim(token::Paren),
+                        SeqSep::trailing_allowed(token::Comma),
+                        |p| Ok(p.parse_expr()?)
+                    ).map(|es| {
                         let nd = self.mk_call(e, es);
-                        hi = self.prev_span;
-                        e = self.mk_expr(lo.to(hi), nd, ThinVec::new());
-                    }
-                    Err(mut err) => { // recover from parse error in argument list
-                        err.emit();
-                        self.consume_block(token::Paren);
-                        hi = self.prev_span;
-                        e = self.mk_expr(lo.to(hi), ExprKind::Err, ThinVec::new());
-                    }
+                        let hi = self.prev_span;
+                        self.mk_expr(lo.to(hi), nd, ThinVec::new())
+                    });
+                    e = self.recover_seq_parse_error(token::Paren, lo, seq);
                 }
-              }
 
-              // expr[...]
-              // Could be either an index expression or a slicing expression.
-              token::OpenDelim(token::Bracket) => {
-                self.bump();
-                let ix = self.parse_expr()?;
-                hi = self.span;
-                self.expect(&token::CloseDelim(token::Bracket))?;
-                let index = self.mk_index(e, ix);
-                e = self.mk_expr(lo.to(hi), index, ThinVec::new())
-              }
-              _ => return Ok(e)
+                // expr[...]
+                // Could be either an index expression or a slicing expression.
+                token::OpenDelim(token::Bracket) => {
+                    self.bump();
+                    let ix = self.parse_expr()?;
+                    hi = self.span;
+                    self.expect(&token::CloseDelim(token::Bracket))?;
+                    let index = self.mk_index(e, ix);
+                    e = self.mk_expr(lo.to(hi), index, ThinVec::new())
+                }
+                _ => return Ok(e)
             }
         }
         return Ok(e);
     }
 
+    fn recover_seq_parse_error(
+        &mut self,
+        delim: token::DelimToken,
+        lo: Span,
+        result: PResult<'a, P<Expr>>,
+    ) -> P<Expr> {
+        match result {
+            Ok(x) => x,
+            Err(mut err) => {
+                err.emit();
+                // recover from parse error
+                self.consume_block(delim);
+                self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
+            }
+        }
+    }
+
     crate fn process_potential_macro_variable(&mut self) {
         let (token, span) = match self.token {
             token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&