about summary refs log tree commit diff
path: root/src/librustc_parse/parser/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_parse/parser/expr.rs')
-rw-r--r--src/librustc_parse/parser/expr.rs86
1 files changed, 34 insertions, 52 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 606714b5fa2..9b106b6db3c 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -442,35 +442,37 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a prefix-unary-operator expr.
-    fn parse_prefix_expr(&mut self, already_parsed_attrs: Option<AttrVec>) -> PResult<'a, P<Expr>> {
-        let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
+    fn parse_prefix_expr(&mut self, attrs: Option<AttrVec>) -> PResult<'a, P<Expr>> {
+        let attrs = self.parse_or_use_outer_attributes(attrs)?;
         let lo = self.token.span;
         // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
         let (hi, ex) = match self.token.kind {
-            token::Not => {
-                self.bump();
-                let e = self.parse_prefix_expr(None);
-                let (span, e) = self.interpolated_or_expr_span(e)?;
-                (lo.to(span), self.mk_unary(UnOp::Not, e))
-            }
-            token::Tilde => self.recover_tilde_expr(lo)?,
-            token::BinOp(token::Minus) => self.parse_neg_expr(lo)?,
-            token::BinOp(token::Star) => self.parse_deref_expr(lo)?,
-            token::BinOp(token::And) | token::AndAnd => self.parse_borrow_expr(lo)?,
-            token::Ident(..) if self.token.is_keyword(kw::Box) => self.parse_box_expr(lo)?,
-            token::Ident(..) if self.is_mistaken_not_ident_negation() => {
-                self.recover_not_expr(lo)?
-            }
+            token::Not => self.parse_unary_expr(lo, UnOp::Not), // `!expr`
+            token::Tilde => self.recover_tilde_expr(lo),        // `~expr`
+            token::BinOp(token::Minus) => self.parse_unary_expr(lo, UnOp::Neg), // `-expr`
+            token::BinOp(token::Star) => self.parse_unary_expr(lo, UnOp::Deref), // `*expr`
+            token::BinOp(token::And) | token::AndAnd => self.parse_borrow_expr(lo),
+            token::Ident(..) if self.token.is_keyword(kw::Box) => self.parse_box_expr(lo),
+            token::Ident(..) if self.is_mistaken_not_ident_negation() => self.recover_not_expr(lo),
             _ => return self.parse_dot_or_call_expr(Some(attrs)),
-        };
-        return Ok(self.mk_expr(lo.to(hi), ex, attrs));
+        }?;
+        Ok(self.mk_expr(lo.to(hi), ex, attrs))
     }
 
-    // Recover on `!` suggesting for bitwise negation instead.
-    fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
+    fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
         self.bump();
         let expr = self.parse_prefix_expr(None);
         let (span, expr) = self.interpolated_or_expr_span(expr)?;
+        Ok((lo.to(span), expr))
+    }
+
+    fn parse_unary_expr(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> {
+        let (span, expr) = self.parse_prefix_expr_common(lo)?;
+        Ok((span, self.mk_unary(op, expr)))
+    }
+
+    // Recover on `!` suggesting for bitwise negation instead.
+    fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
         self.struct_span_err(lo, "`~` cannot be used as a unary operator")
             .span_suggestion_short(
                 lo,
@@ -479,31 +481,13 @@ impl<'a> Parser<'a> {
                 Applicability::MachineApplicable,
             )
             .emit();
-        Ok((lo.to(span), self.mk_unary(UnOp::Not, expr)))
-    }
 
-    /// Parse `-expr`.
-    fn parse_neg_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
-        self.bump(); // `-`
-        let expr = self.parse_prefix_expr(None);
-        let (span, expr) = self.interpolated_or_expr_span(expr)?;
-        Ok((lo.to(span), self.mk_unary(UnOp::Neg, expr)))
-    }
-
-    /// Parse `*expr`.
-    fn parse_deref_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
-        self.bump(); // `*`
-        let expr = self.parse_prefix_expr(None);
-        let (span, expr) = self.interpolated_or_expr_span(expr)?;
-        Ok((lo.to(span), self.mk_unary(UnOp::Deref, expr)))
+        self.parse_unary_expr(lo, UnOp::Not)
     }
 
     /// Parse `box expr`.
     fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
-        self.bump(); // `box`
-        let expr = self.parse_prefix_expr(None);
-        let (span, expr) = self.interpolated_or_expr_span(expr)?;
-        let span = lo.to(span);
+        let (span, expr) = self.parse_prefix_expr_common(lo)?;
         self.sess.gated_spans.gate(sym::box_syntax, span);
         Ok((span, ExprKind::Box(expr)))
     }
@@ -521,26 +505,24 @@ impl<'a> Parser<'a> {
 
     /// Recover on `not expr` in favor of `!expr`.
     fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
-        self.bump();
-        // Emit the error ...
+        // Emit the error...
+        let not_token = self.look_ahead(1, |t| t.clone());
         self.struct_span_err(
-            self.token.span,
-            &format!("unexpected {} after identifier", self.this_token_descr()),
+            not_token.span,
+            &format!("unexpected {} after identifier", super::token_descr(&not_token)),
         )
         .span_suggestion_short(
             // Span the `not` plus trailing whitespace to avoid
             // trailing whitespace after the `!` in our suggestion
-            self.sess.source_map().span_until_non_whitespace(lo.to(self.token.span)),
+            self.sess.source_map().span_until_non_whitespace(lo.to(not_token.span)),
             "use `!` to perform logical negation",
             "!".to_owned(),
             Applicability::MachineApplicable,
         )
         .emit();
-        // —and recover! (just as if we were in the block
-        // for the `token::Not` arm)
-        let expr = self.parse_prefix_expr(None);
-        let (span, e) = self.interpolated_or_expr_span(expr)?;
-        Ok((lo.to(span), self.mk_unary(UnOp::Not, e)))
+
+        // ...and recover!
+        self.parse_unary_expr(lo, UnOp::Not)
     }
 
     /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
@@ -738,7 +720,7 @@ impl<'a> Parser<'a> {
 
     fn error_unexpected_after_dot(&self) {
         // FIXME Could factor this out into non_fatal_unexpected or something.
-        let actual = self.this_token_to_string();
+        let actual = pprust::token_to_string(&self.token);
         self.struct_span_err(self.token.span, &format!("unexpected token: `{}`", actual)).emit();
     }
 
@@ -1142,7 +1124,7 @@ impl<'a> Parser<'a> {
 
     pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
         self.parse_opt_lit().ok_or_else(|| {
-            let msg = format!("unexpected token: {}", self.this_token_descr());
+            let msg = format!("unexpected token: {}", super::token_descr(&self.token));
             self.span_fatal(self.token.span, &msg)
         })
     }