]> git.lizzy.rs Git - rust.git/commitdiff
typeck/expr.rs: extract out check_expr_loop.
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 15 Jun 2019 00:22:52 +0000 (02:22 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sat, 15 Jun 2019 00:22:52 +0000 (02:22 +0200)
src/librustc_typeck/check/expr.rs

index 6bf13f6a2f6a85471449926a710e45e04408ac92..4911486a70d15b8bb3be544d867dedd1dd30806e 100644 (file)
@@ -96,44 +96,7 @@ pub(super) fn check_expr_kind(
                 self.check_expr_while(cond, body, expr)
             }
             ExprKind::Loop(ref body, _, source) => {
-                let coerce = match source {
-                    // you can only use break with a value from a normal `loop { }`
-                    hir::LoopSource::Loop => {
-                        let coerce_to = expected.coercion_target_type(self, body.span);
-                        Some(CoerceMany::new(coerce_to))
-                    }
-
-                    hir::LoopSource::WhileLet |
-                    hir::LoopSource::ForLoop => {
-                        None
-                    }
-                };
-
-                let ctxt = BreakableCtxt {
-                    coerce,
-                    may_break: false, // Will get updated if/when we find a `break`.
-                };
-
-                let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
-                    self.check_block_no_value(&body);
-                });
-
-                if ctxt.may_break {
-                    // No way to know whether it's diverging because
-                    // of a `break` or an outer `break` or `return`.
-                    self.diverges.set(Diverges::Maybe);
-                }
-
-                // If we permit break with a value, then result type is
-                // the LUB of the breaks (possibly ! if none); else, it
-                // is nil. This makes sense because infinite loops
-                // (which would have type !) are only possible iff we
-                // permit break with a value [1].
-                if ctxt.coerce.is_none() && !ctxt.may_break {
-                    // [1]
-                    self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
-                }
-                ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
+                self.check_expr_loop(body, source, expected, expr)
             }
             ExprKind::Match(ref discrim, ref arms, match_src) => {
                 self.check_match(expr, &discrim, arms, expected, match_src)
@@ -796,4 +759,51 @@ fn check_expr_while(
 
         self.tcx.mk_unit()
     }
+
+    fn check_expr_loop(
+        &self,
+        body: &'tcx hir::Block,
+        source: hir::LoopSource,
+        expected: Expectation<'tcx>,
+        expr: &'tcx hir::Expr,
+    ) -> Ty<'tcx> {
+        let coerce = match source {
+            // you can only use break with a value from a normal `loop { }`
+            hir::LoopSource::Loop => {
+                let coerce_to = expected.coercion_target_type(self, body.span);
+                Some(CoerceMany::new(coerce_to))
+            }
+
+            hir::LoopSource::WhileLet |
+            hir::LoopSource::ForLoop => {
+                None
+            }
+        };
+
+        let ctxt = BreakableCtxt {
+            coerce,
+            may_break: false, // Will get updated if/when we find a `break`.
+        };
+
+        let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
+            self.check_block_no_value(&body);
+        });
+
+        if ctxt.may_break {
+            // No way to know whether it's diverging because
+            // of a `break` or an outer `break` or `return`.
+            self.diverges.set(Diverges::Maybe);
+        }
+
+        // If we permit break with a value, then result type is
+        // the LUB of the breaks (possibly ! if none); else, it
+        // is nil. This makes sense because infinite loops
+        // (which would have type !) are only possible iff we
+        // permit break with a value [1].
+        if ctxt.coerce.is_none() && !ctxt.may_break {
+            // [1]
+            self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
+        }
+        ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
+    }
 }