about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/expr.rs
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2022-11-15 08:53:17 +0800
committeryukang <moorekang@gmail.com>2022-11-15 08:53:17 +0800
commit74c9a6c6df5a9fb1a3dc8099f773301e4fc3cdb4 (patch)
tree39643326a8275083638e8059da87498197bac594 /compiler/rustc_parse/src/parser/expr.rs
parent101e1822c3e54e63996c8aaa014d55716f3937eb (diff)
downloadrust-74c9a6c6df5a9fb1a3dc8099f773301e4fc3cdb4.tar.gz
rust-74c9a6c6df5a9fb1a3dc8099f773301e4fc3cdb4.zip
fix #103381, Detect incorrect chaining of if and if let conditions
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs15
1 files changed, 13 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index b072573af23..9dc0fb86312 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -24,8 +24,8 @@ use crate::errors::{
     NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
     OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
     RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
-    StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
-    UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
+    StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf,
+    UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
 };
 use crate::maybe_recover_from_interpolated_ty_qpath;
 
@@ -2279,6 +2279,7 @@ impl<'a> Parser<'a> {
                 if let Some(block) = recover_block_from_condition(self) {
                     block
                 } else {
+                    self.error_on_extra_if(&cond)?;
                     // Parse block, which will always fail, but we can add a nice note to the error
                     self.parse_block().map_err(|mut err| {
                         err.span_note(
@@ -2415,6 +2416,16 @@ impl<'a> Parser<'a> {
         });
     }
 
+    fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
+        if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind &&
+            let BinOpKind::And = binop &&
+            let ExprKind::If(cond, ..) = &right.kind {
+                    Err(self.sess.create_err(UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo()))))
+            } else {
+                Ok(())
+            }
+    }
+
     /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
     fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         // Record whether we are about to parse `for (`.