about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authornx2k3 <nx2k3@duck.com>2023-02-26 16:17:23 +0000
committernx2k3 <nx2k3@duck.com>2023-02-26 16:17:23 +0000
commit46ea12a499aecd655a5c954431466db0a66e8ec9 (patch)
treea81e5ca4513c95bf96f7f9f50696fb1c9422f0b9 /compiler/rustc_parse/src
parent70fd012439d75fd6ce561a6518b9b8fd399f455f (diff)
downloadrust-46ea12a499aecd655a5c954431466db0a66e8ec9.tar.gz
rust-46ea12a499aecd655a5c954431466db0a66e8ec9.zip
fix #108495, postfix decrement and prefix decrement has no warning
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs29
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs33
2 files changed, 55 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index d235b8a8176..e3dbe89b56c 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -166,7 +166,7 @@ enum IsStandalone {
 enum IncOrDec {
     Inc,
     // FIXME: `i--` recovery isn't implemented yet
-    #[allow(dead_code)]
+    // #[allow(dead_code)]
     Dec,
 }
 
@@ -1331,7 +1331,7 @@ impl<'a> Parser<'a> {
 
         Ok(())
     }
-
+    #[allow(dead_code)]
     pub(super) fn recover_from_prefix_increment(
         &mut self,
         operand_expr: P<Expr>,
@@ -1342,7 +1342,7 @@ impl<'a> Parser<'a> {
         let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre };
         self.recover_from_inc_dec(operand_expr, kind, op_span)
     }
-
+    #[allow(dead_code)]
     pub(super) fn recover_from_postfix_increment(
         &mut self,
         operand_expr: P<Expr>,
@@ -1356,7 +1356,30 @@ impl<'a> Parser<'a> {
         };
         self.recover_from_inc_dec(operand_expr, kind, op_span)
     }
+    pub(super) fn recover_from_prefix_decrement(
+        &mut self,
+        operand_expr: P<Expr>,
+        op_span: Span,
+        start_stmt: bool,
+    ) -> PResult<'a, P<Expr>> {
+        let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr };
+        let kind = IncDecRecovery { standalone, op: IncOrDec::Dec, fixity: UnaryFixity::Pre };
+        self.recover_from_inc_dec(operand_expr, kind, op_span)
+    }
 
+    pub(super) fn recover_from_postfix_decrement(
+        &mut self,
+        operand_expr: P<Expr>,
+        op_span: Span,
+        start_stmt: bool,
+    ) -> PResult<'a, P<Expr>> {
+        let kind = IncDecRecovery {
+            standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
+            op: IncOrDec::Dec,
+            fixity: UnaryFixity::Post,
+        };
+        self.recover_from_inc_dec(operand_expr, kind, op_span)
+    }
     fn recover_from_inc_dec(
         &mut self,
         base: P<Expr>,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 12f65a436e3..2004d0a8fe7 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -281,6 +281,16 @@ impl<'a> Parser<'a> {
                 lhs = self.recover_from_postfix_increment(lhs, op_span, starts_stmt)?;
                 continue;
             }
+            if self.prev_token == token::BinOp(token::Minus)
+                && self.token == token::BinOp(token::Minus)
+                && self.prev_token.span.between(self.token.span).is_empty()
+            {
+                let op_span = self.prev_token.span.to(self.token.span);
+                // Eat the second `+`
+                self.bump();
+                lhs = self.recover_from_postfix_decrement(lhs, op_span, starts_stmt)?;
+                continue;
+            }
 
             let op = op.node;
             // Special cases:
@@ -550,10 +560,7 @@ impl<'a> Parser<'a> {
             token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)),
             // `~expr`
             token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)),
-            // `-expr`
-            token::BinOp(token::Minus) => {
-                make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
-            }
+
             // `*expr`
             token::BinOp(token::Star) => {
                 make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref))
@@ -595,6 +602,24 @@ impl<'a> Parser<'a> {
                 let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
                 this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt)
             }
+            // Recover from `++x`:
+            token::BinOp(token::Minus)
+                if this.look_ahead(1, |t| *t == token::BinOp(token::Minus)) =>
+            {
+                let starts_stmt = this.prev_token == token::Semi
+                    || this.prev_token == token::CloseDelim(Delimiter::Brace);
+                let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
+                // Eat both `+`s.
+                this.bump();
+                this.bump();
+
+                let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
+                this.recover_from_prefix_decrement(operand_expr, pre_span, starts_stmt)
+            }
+            // `-expr`
+            token::BinOp(token::Minus) => {
+                make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
+            }
             token::Ident(..) if this.token.is_keyword(kw::Box) => {
                 make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
             }