From f8b32dfb27976f52b47bb278fee397b65efddc18 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 19 Jun 2019 17:21:28 +0200 Subject: [PATCH 01/12] Remove ExprKind::While from HIR. --- src/librustc/cfg/construct.rs | 42 ------------- src/librustc/hir/intravisit.rs | 5 -- src/librustc/hir/lowering.rs | 50 +++++++++++++--- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 21 +++++-- src/librustc/hir/print.rs | 11 ---- src/librustc/middle/expr_use_visitor.rs | 5 -- src/librustc/middle/liveness.rs | 63 ++++---------------- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/region.rs | 5 -- src/librustc/middle/resolve_lifetime.rs | 9 ++- src/librustc_lint/builtin.rs | 18 +++++- src/librustc_mir/build/expr/into.rs | 51 ++++------------ src/librustc_mir/hair/cx/expr.rs | 7 --- src/librustc_mir/hair/mod.rs | 1 - src/librustc_mir/hair/pattern/check_match.rs | 3 +- src/librustc_passes/loops.rs | 32 ++-------- src/librustc_passes/rvalue_promotion.rs | 7 --- src/librustc_typeck/check/expr.rs | 41 +------------ src/librustc_typeck/check/mod.rs | 1 - 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 a132575b0c673..f81d18694136e 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 9c05f18762df1..2d82314f86ac2 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 ef05b57fb8f7d..011808a7ff96c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4461,11 +4461,11 @@ impl<'a> LoweringContext<'a> { }; // `match { ... }` - 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 79b343ecfe29a..63f60d0ab9528 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 bfbd8398f99f3..7b760a872387e 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), - /// A while loop, with an optional label - /// - /// I.e., `'label: while expr { }`. - While(P, P, Option