diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-06-19 17:21:28 +0200 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-07-06 06:43:58 +0200 |
| commit | f8b32dfb27976f52b47bb278fee397b65efddc18 (patch) | |
| tree | 7a816eeb3b3e45500b5f566fcea6107f737b50ca | |
| parent | 481068a707679257e2a738b40987246e0420e787 (diff) | |
| download | rust-f8b32dfb27976f52b47bb278fee397b65efddc18.tar.gz rust-f8b32dfb27976f52b47bb278fee397b65efddc18.zip | |
Remove ExprKind::While from HIR.
| -rw-r--r-- | src/librustc/cfg/construct.rs | 42 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 5 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 50 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 21 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 11 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/liveness.rs | 63 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/region.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/resolve_lifetime.rs | 9 | ||||
| -rw-r--r-- | src/librustc_lint/builtin.rs | 18 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 51 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 7 | ||||
| -rw-r--r-- | src/librustc_mir/hair/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/hair/pattern/check_match.rs | 3 | ||||
| -rw-r--r-- | src/librustc_passes/loops.rs | 32 | ||||
| -rw-r--r-- | src/librustc_passes/rvalue_promotion.rs | 7 | ||||
| -rw-r--r-- | src/librustc_typeck/check/expr.rs | 41 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_typeck/check/regionck.rs | 10 |
21 files changed, 114 insertions, 272 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index a132575b0c6..f81d1869413 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -165,48 +165,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.add_ast_node(expr.hir_id.local_id, &[blk_exit]) } - hir::ExprKind::While(ref cond, ref body, _) => { - // - // [pred] - // | - // v 1 - // [loopback] <--+ 5 - // | | - // v 2 | - // +-----[cond] | - // | | | - // | v 4 | - // | [body] -----+ - // v 3 - // [expr] - // - // Note that `break` and `continue` statements - // may cause additional edges. - - let loopback = self.add_dummy_node(&[pred]); // 1 - - // Create expr_exit without pred (cond_exit) - let expr_exit = self.add_ast_node(expr.hir_id.local_id, &[]); // 3 - - // The LoopScope needs to be on the loop_scopes stack while evaluating the - // condition and the body of the loop (both can break out of the loop) - self.loop_scopes.push(LoopScope { - loop_id: expr.hir_id.local_id, - continue_index: loopback, - break_index: expr_exit - }); - - let cond_exit = self.expr(&cond, loopback); // 2 - - // Add pred (cond_exit) to expr_exit - self.add_contained_edge(cond_exit, expr_exit); - - let body_exit = self.block(&body, cond_exit); // 4 - self.add_contained_edge(body_exit, loopback); // 5 - self.loop_scopes.pop(); - expr_exit - } - hir::ExprKind::Loop(ref body, _, _) => { // // [pred] diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 9c05f18762d..2d82314f86a 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1026,11 +1026,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprKind::DropTemps(ref subexpression) => { visitor.visit_expr(subexpression); } - ExprKind::While(ref subexpression, ref block, ref opt_label) => { - walk_list!(visitor, visit_label, opt_label); - visitor.visit_expr(subexpression); - visitor.visit_block(block); - } ExprKind::Loop(ref block, ref opt_label, _) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index ef05b57fb8f..011808a7ff9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4461,11 +4461,11 @@ impl<'a> LoweringContext<'a> { }; // `match <sub_expr> { ... }` - let arms = hir_vec![pat_arm, break_arm]; - let match_expr = self.expr( + let match_expr = self.expr_match( sub_expr.span, - hir::ExprKind::Match(sub_expr, arms, hir::MatchSource::WhileLetDesugar), - ThinVec::new(), + sub_expr, + hir_vec![pat_arm, break_arm], + hir::MatchSource::WhileLetDesugar, ); // `[opt_ident]: loop { ... }` @@ -4479,10 +4479,46 @@ impl<'a> LoweringContext<'a> { loop_expr } else { self.with_loop_scope(e.id, |this| { - hir::ExprKind::While( - this.with_loop_condition_scope(|this| P(this.lower_expr(cond))), - this.lower_block(body, false), + // We desugar: `'label: while $cond $body` into: + // + // ``` + // 'label: loop { + // match DropTemps($cond) { + // true => $block, + // _ => break, + // } + // } + // ``` + + // `true => then`: + let then_pat = this.pat_bool(e.span, true); + let then_blk = this.lower_block(body, false); + let then_expr = this.expr_block(then_blk, ThinVec::new()); + let then_arm = this.arm(hir_vec![then_pat], P(then_expr)); + + // `_ => break`: + let else_pat = this.pat_wild(e.span); + let else_expr = this.expr_break(e.span, ThinVec::new()); + let else_arm = this.arm(hir_vec![else_pat], else_expr); + + // Lower condition: + let cond = this.with_loop_condition_scope(|this| this.lower_expr(cond)); + // Wrap in a construct equivalent to `{ let _t = $cond; _t }` + // to preserve drop semantics since `if cond { ... }` does not + // let temporaries live outside of `cond`. + let cond = this.expr_drop_temps(cond.span, P(cond), ThinVec::new()); + + let match_expr = this.expr_match( + cond.span, + P(cond), + vec![then_arm, else_arm].into(), + hir::MatchSource::WhileDesugar, + ); + + hir::ExprKind::Loop( + P(this.block_expr(P(match_expr))), this.lower_label(opt_label), + hir::LoopSource::While, ) }) } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 79b343ecfe2..63f60d0ab95 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -731,7 +731,7 @@ impl<'hir> Map<'hir> { match *node { Node::Expr(ref expr) => { match expr.node { - ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Ret(..) => true, + ExprKind::Loop(..) | ExprKind::Ret(..) => true, _ => false, } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index bfbd8398f99..7b760a87238 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1405,7 +1405,6 @@ impl Expr { ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::DropTemps(ref expr, ..) => expr.precedence(), - ExprKind::While(..) => ExprPrecedence::While, ExprKind::Loop(..) => ExprPrecedence::Loop, ExprKind::Match(..) => ExprPrecedence::Match, ExprKind::Closure(..) => ExprPrecedence::Closure, @@ -1464,7 +1463,6 @@ impl Expr { ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | - ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Assign(..) | ExprKind::InlineAsm(..) | @@ -1532,10 +1530,6 @@ pub enum ExprKind { /// This construct only exists to tweak the drop order in HIR lowering. /// An example of that is the desugaring of `for` loops. DropTemps(P<Expr>), - /// A while loop, with an optional label - /// - /// I.e., `'label: while expr { <block> }`. - While(P<Expr>, P<Block>, Option<Label>), /// A conditionless loop (can be exited with `break`, `continue`, or `return`). /// /// I.e., `'label: loop { <block> }`. @@ -1653,6 +1647,8 @@ pub enum MatchSource { IfLetDesugar { contains_else_clause: bool, }, + /// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`). + WhileDesugar, /// A `while let _ = _ { .. }` (which was desugared to a /// `loop { match _ { .. } }`). WhileLetDesugar, @@ -1669,12 +1665,25 @@ pub enum MatchSource { pub enum LoopSource { /// A `loop { .. }` loop. Loop, + /// A `while _ { .. }` loop. + While, /// A `while let _ = _ { .. }` loop. WhileLet, /// A `for _ in _ { .. }` loop. ForLoop, } +impl LoopSource { + pub fn name(self) -> &'static str { + match self { + LoopSource::Loop => "loop", + LoopSource::While => "while", + LoopSource::WhileLet => "while let", + LoopSource::ForLoop => "for", + } + } +} + #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum LoopIdError { OutsideLoopScope, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 573b9add133..367e4dba042 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1299,16 +1299,6 @@ impl<'a> State<'a> { // Print `}`: self.bclose_maybe_open(expr.span, indent_unit, true); } - hir::ExprKind::While(ref test, ref blk, opt_label) => { - if let Some(label) = opt_label { - self.print_ident(label.ident); - self.word_space(":"); - } - self.head("while"); - self.print_expr_as_cond(&test); - self.s.space(); - self.print_block(&blk); - } hir::ExprKind::Loop(ref blk, opt_label, _) => { if let Some(label) = opt_label { self.print_ident(label.ident); @@ -2289,7 +2279,6 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { match e.node { hir::ExprKind::Match(..) | hir::ExprKind::Block(..) | - hir::ExprKind::While(..) | hir::ExprKind::Loop(..) => false, _ => true, } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 77094604eda..2448db032b9 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -487,11 +487,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.walk_block(&blk); } - hir::ExprKind::While(ref cond_expr, ref blk, _) => { - self.consume_expr(&cond_expr); - self.walk_block(&blk); - } - hir::ExprKind::Unary(_, ref lhs) => { self.consume_expr(&lhs); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index c4d60b676b2..3885d1b6f82 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -93,7 +93,6 @@ //! It is the responsibility of typeck to ensure that there are no //! `return` expressions in a function declared as diverging. -use self::LoopKind::*; use self::LiveNodeKind::*; use self::VarKind::*; @@ -120,14 +119,6 @@ use crate::hir::{Expr, HirId}; use crate::hir::def_id::DefId; use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; -/// For use with `propagate_through_loop`. -enum LoopKind<'a> { - /// An endless `loop` loop. - LoopLoop, - /// A `while` loop, with the given expression as condition. - WhileLoop(&'a Expr), -} - #[derive(Copy, Clone, PartialEq)] struct Variable(u32); @@ -517,7 +508,6 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) { // live nodes required for interesting control flow: hir::ExprKind::Match(..) | - hir::ExprKind::While(..) | hir::ExprKind::Loop(..) => { ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); @@ -1055,14 +1045,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { }) } - hir::ExprKind::While(ref cond, ref blk, _) => { - self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ) - } - // Note that labels have been resolved, so we don't need to look // at the label ident hir::ExprKind::Loop(ref blk, _, _) => { - self.propagate_through_loop(expr, LoopLoop, &blk, succ) + self.propagate_through_loop(expr, &blk, succ) } hir::ExprKind::Match(ref e, ref arms, _) => { @@ -1353,13 +1339,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn propagate_through_loop(&mut self, - expr: &Expr, - kind: LoopKind<'_>, - body: &hir::Block, - succ: LiveNode) - -> LiveNode { + fn propagate_through_loop( + &mut self, + expr: &Expr, + body: &hir::Block, + succ: LiveNode + ) -> LiveNode { /* + FIXME: clean up this description. We model control flow like this: @@ -1377,50 +1364,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { */ - // first iteration: let mut first_merge = true; let ln = self.live_node(expr.hir_id, expr.span); self.init_empty(ln, succ); - match kind { - LoopLoop => {} - _ => { - // If this is not a `loop` loop, then it's possible we bypass - // the body altogether. Otherwise, the only way is via a `break` - // in the loop body. - self.merge_from_succ(ln, succ, first_merge); - first_merge = false; - } - } debug!("propagate_through_loop: using id for loop body {} {}", expr.hir_id, self.ir.tcx.hir().hir_to_pretty_string(body.hir_id)); self.break_ln.insert(expr.hir_id, succ); - let cond_ln = match kind { - LoopLoop => ln, - WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln), - }; - - self.cont_ln.insert(expr.hir_id, cond_ln); + self.cont_ln.insert(expr.hir_id, ln); - let body_ln = self.propagate_through_block(body, cond_ln); + let body_ln = self.propagate_through_block(body, ln); // repeat until fixed point is reached: while self.merge_from_succ(ln, body_ln, first_merge) { first_merge = false; - - let new_cond_ln = match kind { - LoopLoop => ln, - WhileLoop(ref cond) => { - self.propagate_through_expr(&cond, ln) - } - }; - assert_eq!(cond_ln, new_cond_ln); - assert_eq!(body_ln, self.propagate_through_block(body, cond_ln)); + assert_eq!(body_ln, self.propagate_through_block(body, ln)); } - cond_ln + ln } } @@ -1520,7 +1483,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { // no correctness conditions related to liveness hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) | - hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) | + hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Index(..) | hir::ExprKind::Field(..) | hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | hir::ExprKind::Unary(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 088c862dcb8..66d8a2cc111 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -696,7 +696,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) | hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | - hir::ExprKind::Binary(..) | hir::ExprKind::While(..) | + hir::ExprKind::Binary(..) | hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) | hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 26ac1275bb9..88c19715811 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -915,11 +915,6 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h terminating(body.hir_id.local_id); } - hir::ExprKind::While(ref expr, ref body, _) => { - terminating(expr.hir_id.local_id); - terminating(body.hir_id.local_id); - } - hir::ExprKind::DropTemps(ref expr) => { // `DropTemps(expr)` does not denote a conditional scope. // Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`. diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 0839a2b435a..3221b41ee1d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1201,11 +1201,10 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) { } fn expression_label(ex: &hir::Expr) -> Option<ast::Ident> { - match ex.node { - hir::ExprKind::While(.., Some(label)) | hir::ExprKind::Loop(_, Some(label), _) => { - Some(label.ident) - } - _ => None, + if let hir::ExprKind::Loop(_, Some(label), _) = ex.node { + Some(label.ident) + } else { + None } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 267b09bae35..d98dfb5478a 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -64,9 +64,25 @@ declare_lint! { declare_lint_pass!(WhileTrue => [WHILE_TRUE]); +fn as_while_cond(expr: &hir::Expr) -> Option<&hir::Expr> { + if let hir::ExprKind::Loop(blk, ..) = &expr.node { + if let Some(match_expr) = &blk.expr { + if let hir::ExprKind::Match(cond, .., hir::MatchSource::WhileDesugar) + = &match_expr.node + { + if let hir::ExprKind::DropTemps(cond) = &cond.node { + return Some(cond); + } + } + } + } + + None +} + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue { fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) { - if let hir::ExprKind::While(ref cond, ..) = e.node { + if let Some(ref cond) = as_while_cond(e) { if let hir::ExprKind::Lit(ref lit) = cond.node { if let ast::LitKind::Bool(true) = lit.node { if lit.span.ctxt() == SyntaxContext::empty() { diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 0a2ea78bfd7..e433da904a6 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -138,19 +138,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { join_block.unit() } - ExprKind::Loop { - condition: opt_cond_expr, - body, - } => { - // [block] --> [loop_block] -/eval. cond./-> [loop_block_end] -1-> [exit_block] - // ^ | - // | 0 - // | | - // | v - // [body_block_end] <-/eval. body/-- [body_block] - // - // If `opt_cond_expr` is `None`, then the graph is somewhat simplified: - // + ExprKind::Loop { body } => { // [block] // | // [loop_block] -> [body_block] -/eval. body/-> [body_block_end] @@ -177,33 +165,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination.clone(), move |this| { // conduct the test, if necessary - let body_block; - if let Some(cond_expr) = opt_cond_expr { - let cond_expr = this.hir.mirror(cond_expr); - let (true_block, false_block) - = this.test_bool(loop_block, cond_expr, source_info); - body_block = true_block; - - // if the test is false, there's no `break` to assign `destination`, so - // we have to do it - this.cfg.push_assign_unit(false_block, source_info, destination); - this.cfg.terminate( - false_block, - source_info, - TerminatorKind::Goto { target: exit_block }, - ); - } else { - body_block = this.cfg.start_new_block(); - let diverge_cleanup = this.diverge_cleanup(); - this.cfg.terminate( - loop_block, - source_info, - TerminatorKind::FalseUnwind { - real_target: body_block, - unwind: Some(diverge_cleanup), - }, - ) - } + let body_block = this.cfg.start_new_block(); + let diverge_cleanup = this.diverge_cleanup(); + this.cfg.terminate( + loop_block, + source_info, + TerminatorKind::FalseUnwind { + real_target: body_block, + unwind: Some(diverge_cleanup), + }, + ); // The “return” value of the loop body must always be an unit. We therefore // introduce a unit temporary as the destination for the loop body. diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e7663ddaa98..242afcf5abb 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -599,15 +599,8 @@ fn make_mirror_unadjusted<'a, 'tcx>( arms: arms.iter().map(|a| convert_arm(cx, a)).collect(), } } - hir::ExprKind::While(ref cond, ref body, _) => { - ExprKind::Loop { - condition: Some(cond.to_ref()), - body: block::to_expr_ref(cx, body), - } - } hir::ExprKind::Loop(ref body, _, _) => { ExprKind::Loop { - condition: None, body: block::to_expr_ref(cx, body), } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 5431a31c4bb..0638cb462f7 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -173,7 +173,6 @@ pub enum ExprKind<'tcx> { source: ExprRef<'tcx>, }, Loop { - condition: Option<ExprRef<'tcx>>, body: ExprRef<'tcx>, }, Match { diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 915ce9f20d0..d822a26ce59 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -371,7 +371,8 @@ fn check_arms<'a, 'tcx>( match is_useful(cx, &seen, &v, LeaveOutWitness) { NotUseful => { match source { - hir::MatchSource::IfDesugar { .. } => bug!(), + hir::MatchSource::IfDesugar { .. } | + hir::MatchSource::WhileDesugar => bug!(), hir::MatchSource::IfLetDesugar { .. } => { cx.tcx.lint_hir( lint::builtin::IRREFUTABLE_LET_PATTERNS, diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 616e6974110..afe4c78dcfc 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -13,26 +13,9 @@ use syntax_pos::Span; use errors::Applicability; #[derive(Clone, Copy, Debug, PartialEq)] -enum LoopKind { - Loop(hir::LoopSource), - WhileLoop, -} - -impl LoopKind { - fn name(self) -> &'static str { - match self { - LoopKind::Loop(hir::LoopSource::Loop) => "loop", - LoopKind::Loop(hir::LoopSource::WhileLet) => "while let", - LoopKind::Loop(hir::LoopSource::ForLoop) => "for", - LoopKind::WhileLoop => "while", - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq)] enum Context { Normal, - Loop(LoopKind), + Loop(hir::LoopSource), Closure, LabeledBlock, AnonConst, @@ -71,14 +54,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { fn visit_expr(&mut self, e: &'hir hir::Expr) { match e.node { - hir::ExprKind::While(ref e, ref b, _) => { - self.with_context(Loop(LoopKind::WhileLoop), |v| { - v.visit_expr(&e); - v.visit_block(&b); - }); - } hir::ExprKind::Loop(ref b, _, source) => { - self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b)); + self.with_context(Loop(source), |v| v.visit_block(&b)); } hir::ExprKind::Closure(_, ref function_decl, b, _, _) => { self.visit_fn_decl(&function_decl); @@ -117,15 +94,14 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { None } else { Some(match self.hir_map.expect_expr(loop_id).node { - hir::ExprKind::While(..) => LoopKind::WhileLoop, - hir::ExprKind::Loop(_, _, source) => LoopKind::Loop(source), + hir::ExprKind::Loop(_, _, source) => source, ref r => span_bug!(e.span, "break label resolved to a non-loop: {:?}", r), }) }; match loop_kind { None | - Some(LoopKind::Loop(hir::LoopSource::Loop)) => (), + Some(hir::LoopSource::Loop) => (), Some(kind) => { struct_span_err!(self.sess, e.span, E0571, "`break` with value from a `{}` loop", diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index daa64478bca..8ba3a25e394 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -520,13 +520,6 @@ fn check_expr_kind<'a, 'tcx>( NotPromotable } - // Loops (not very meaningful in constants). - hir::ExprKind::While(ref expr, ref box_block, ref _option_label) => { - let _ = v.check_expr(expr); - let _ = v.check_block(box_block); - NotPromotable - } - hir::ExprKind::Loop(ref box_block, ref _option_label, ref _loop_source) => { let _ = v.check_block(box_block); NotPromotable diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 603726dfe23..b02a7c21027 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -159,11 +159,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Warn for non-block expressions with diverging children. match expr.node { - ExprKind::Block(..) | - ExprKind::Loop(..) | ExprKind::While(..) | - ExprKind::Match(..) => {} - - _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression") + ExprKind::Block(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {}, + _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"), } // Any expression that produces a value of type `!` must have diverged @@ -245,9 +242,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Assign(ref lhs, ref rhs) => { self.check_expr_assign(expr, expected, lhs, rhs) } - ExprKind::While(ref cond, ref body, _) => { - self.check_expr_while(cond, body, expr) - } ExprKind::Loop(ref body, _, source) => { self.check_expr_loop(body, source, expected, expr) } @@ -702,36 +696,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_expr_while( - &self, - cond: &'tcx hir::Expr, - body: &'tcx hir::Block, - expr: &'tcx hir::Expr - ) -> Ty<'tcx> { - let ctxt = BreakableCtxt { - // Cannot use break with a value from a while loop. - coerce: None, - may_break: false, // Will get updated if/when we find a `break`. - }; - - let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || { - self.check_expr_has_type_or_error(&cond, self.tcx.types.bool); - let cond_diverging = self.diverges.get(); - self.check_block_no_value(&body); - - // We may never reach the body so it diverging means nothing. - self.diverges.set(cond_diverging); - }); - - 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); - } - - self.tcx.mk_unit() - } - fn check_expr_loop( &self, body: &'tcx hir::Block, @@ -746,6 +710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(CoerceMany::new(coerce_to)) } + hir::LoopSource::While | hir::LoopSource::WhileLet | hir::LoopSource::ForLoop => { None diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index efe9079e19e..5b19614a5b3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3865,7 +3865,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match expression.node { ExprKind::Call(..) | ExprKind::MethodCall(..) | - ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::Block(..) => { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index c66d746d6e0..f9ebe762e52 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -685,16 +685,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> { self.set_repeating_scope(repeating_scope); } - hir::ExprKind::While(ref cond, ref body, _) => { - let repeating_scope = self.set_repeating_scope(cond.hir_id); - self.visit_expr(&cond); - - self.set_repeating_scope(body.hir_id); - self.visit_block(&body); - - self.set_repeating_scope(repeating_scope); - } - hir::ExprKind::Ret(Some(ref ret_expr)) => { let call_site_scope = self.call_site_scope; debug!( |
