]> git.lizzy.rs Git - rust.git/commitdiff
lowering: extract lower_expr_let
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 10 Aug 2019 13:42:08 +0000 (15:42 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sat, 10 Aug 2019 18:24:43 +0000 (20:24 +0200)
src/librustc/hir/lowering/expr.rs

index 547224f35cf7e84af3da14344d1d4d5c0a5b632f..25a77f95a57931aa36a4d9e9f1e60b2961a4a43a 100644 (file)
@@ -67,40 +67,7 @@ pub(super) fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::AddrOf(m, ohs)
             }
-            ExprKind::Let(ref pats, ref scrutinee) => {
-                // If we got here, the `let` expression is not allowed.
-                self.sess
-                    .struct_span_err(e.span, "`let` expressions are not supported here")
-                    .note("only supported directly in conditions of `if`- and `while`-expressions")
-                    .note("as well as when nested within `&&` and parenthesis in those conditions")
-                    .emit();
-
-                // For better recovery, we emit:
-                // ```
-                // match scrutinee { pats => true, _ => false }
-                // ```
-                // While this doesn't fully match the user's intent, it has key advantages:
-                // 1. We can avoid using `abort_if_errors`.
-                // 2. We can typeck both `pats` and `scrutinee`.
-                // 3. `pats` is allowed to be refutable.
-                // 4. The return type of the block is `bool` which seems like what the user wanted.
-                let scrutinee = self.lower_expr(scrutinee);
-                let then_arm = {
-                    let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
-                    let expr = self.expr_bool(e.span, true);
-                    self.arm(pats, P(expr))
-                };
-                let else_arm = {
-                    let pats = hir_vec![self.pat_wild(e.span)];
-                    let expr = self.expr_bool(e.span, false);
-                    self.arm(pats, P(expr))
-                };
-                hir::ExprKind::Match(
-                    P(scrutinee),
-                    vec![then_arm, else_arm].into(),
-                    hir::MatchSource::Normal,
-                )
-            }
+            ExprKind::Let(ref pats, ref scrutinee) => self.lower_expr_let(e.span, pats, scrutinee),
             ExprKind::If(ref cond, ref then, ref else_opt) => {
                 self.lower_expr_if(e.span, cond, then, else_opt.as_deref())
             }
@@ -240,6 +207,50 @@ pub(super) fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
         }
     }
 
+    /// Emit an error and lower `ast::ExprKind::Let(pats, scrutinee)` into:
+    /// ```rust
+    /// match scrutinee { pats => true, _ => false }
+    /// ```
+    fn lower_expr_let(
+        &mut self,
+        span: Span,
+        pats: &[AstP<Pat>],
+        scrutinee: &Expr
+    ) -> hir::ExprKind {
+        // If we got here, the `let` expression is not allowed.
+        self.sess
+            .struct_span_err(span, "`let` expressions are not supported here")
+            .note("only supported directly in conditions of `if`- and `while`-expressions")
+            .note("as well as when nested within `&&` and parenthesis in those conditions")
+            .emit();
+
+        // For better recovery, we emit:
+        // ```
+        // match scrutinee { pats => true, _ => false }
+        // ```
+        // While this doesn't fully match the user's intent, it has key advantages:
+        // 1. We can avoid using `abort_if_errors`.
+        // 2. We can typeck both `pats` and `scrutinee`.
+        // 3. `pats` is allowed to be refutable.
+        // 4. The return type of the block is `bool` which seems like what the user wanted.
+        let scrutinee = self.lower_expr(scrutinee);
+        let then_arm = {
+            let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
+            let expr = self.expr_bool(span, true);
+            self.arm(pats, P(expr))
+        };
+        let else_arm = {
+            let pats = hir_vec![self.pat_wild(span)];
+            let expr = self.expr_bool(span, false);
+            self.arm(pats, P(expr))
+        };
+        hir::ExprKind::Match(
+            P(scrutinee),
+            vec![then_arm, else_arm].into(),
+            hir::MatchSource::Normal,
+        )
+    }
+
     fn lower_expr_if(
         &mut self,
         span: Span,