Skip to content

Commit 7f26d26

Browse files
committed
Remove ExprKind::While from HIR.
1 parent d3e2cec commit 7f26d26

File tree

21 files changed

+114
-272
lines changed

21 files changed

+114
-272
lines changed

src/librustc/cfg/construct.rs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -165,48 +165,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
165165
self.add_ast_node(expr.hir_id.local_id, &[blk_exit])
166166
}
167167

168-
hir::ExprKind::While(ref cond, ref body, _) => {
169-
//
170-
// [pred]
171-
// |
172-
// v 1
173-
// [loopback] <--+ 5
174-
// | |
175-
// v 2 |
176-
// +-----[cond] |
177-
// | | |
178-
// | v 4 |
179-
// | [body] -----+
180-
// v 3
181-
// [expr]
182-
//
183-
// Note that `break` and `continue` statements
184-
// may cause additional edges.
185-
186-
let loopback = self.add_dummy_node(&[pred]); // 1
187-
188-
// Create expr_exit without pred (cond_exit)
189-
let expr_exit = self.add_ast_node(expr.hir_id.local_id, &[]); // 3
190-
191-
// The LoopScope needs to be on the loop_scopes stack while evaluating the
192-
// condition and the body of the loop (both can break out of the loop)
193-
self.loop_scopes.push(LoopScope {
194-
loop_id: expr.hir_id.local_id,
195-
continue_index: loopback,
196-
break_index: expr_exit
197-
});
198-
199-
let cond_exit = self.expr(&cond, loopback); // 2
200-
201-
// Add pred (cond_exit) to expr_exit
202-
self.add_contained_edge(cond_exit, expr_exit);
203-
204-
let body_exit = self.block(&body, cond_exit); // 4
205-
self.add_contained_edge(body_exit, loopback); // 5
206-
self.loop_scopes.pop();
207-
expr_exit
208-
}
209-
210168
hir::ExprKind::Loop(ref body, _, _) => {
211169
//
212170
// [pred]

src/librustc/hir/intravisit.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,11 +1026,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10261026
ExprKind::DropTemps(ref subexpression) => {
10271027
visitor.visit_expr(subexpression);
10281028
}
1029-
ExprKind::While(ref subexpression, ref block, ref opt_label) => {
1030-
walk_list!(visitor, visit_label, opt_label);
1031-
visitor.visit_expr(subexpression);
1032-
visitor.visit_block(block);
1033-
}
10341029
ExprKind::Loop(ref block, ref opt_label, _) => {
10351030
walk_list!(visitor, visit_label, opt_label);
10361031
visitor.visit_block(block);

src/librustc/hir/lowering.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4459,11 +4459,11 @@ impl<'a> LoweringContext<'a> {
44594459
};
44604460

44614461
// `match <sub_expr> { ... }`
4462-
let arms = hir_vec![pat_arm, break_arm];
4463-
let match_expr = self.expr(
4462+
let match_expr = self.expr_match(
44644463
sub_expr.span,
4465-
hir::ExprKind::Match(sub_expr, arms, hir::MatchSource::WhileLetDesugar),
4466-
ThinVec::new(),
4464+
sub_expr,
4465+
hir_vec![pat_arm, break_arm],
4466+
hir::MatchSource::WhileLetDesugar,
44674467
);
44684468

44694469
// `[opt_ident]: loop { ... }`
@@ -4477,10 +4477,46 @@ impl<'a> LoweringContext<'a> {
44774477
loop_expr
44784478
} else {
44794479
self.with_loop_scope(e.id, |this| {
4480-
hir::ExprKind::While(
4481-
this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
4482-
this.lower_block(body, false),
4480+
// We desugar: `'label: while $cond $body` into:
4481+
//
4482+
// ```
4483+
// 'label: loop {
4484+
// match DropTemps($cond) {
4485+
// true => $block,
4486+
// _ => break,
4487+
// }
4488+
// }
4489+
// ```
4490+
4491+
// `true => then`:
4492+
let then_pat = this.pat_bool(e.span, true);
4493+
let then_blk = this.lower_block(body, false);
4494+
let then_expr = this.expr_block(then_blk, ThinVec::new());
4495+
let then_arm = this.arm(hir_vec![then_pat], P(then_expr));
4496+
4497+
// `_ => break`:
4498+
let else_pat = this.pat_wild(e.span);
4499+
let else_expr = this.expr_break(e.span, ThinVec::new());
4500+
let else_arm = this.arm(hir_vec![else_pat], else_expr);
4501+
4502+
// Lower condition:
4503+
let cond = this.with_loop_condition_scope(|this| this.lower_expr(cond));
4504+
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4505+
// to preserve drop semantics since `if cond { ... }` does not
4506+
// let temporaries live outside of `cond`.
4507+
let cond = this.expr_drop_temps(cond.span, P(cond), ThinVec::new());
4508+
4509+
let match_expr = this.expr_match(
4510+
cond.span,
4511+
P(cond),
4512+
vec![then_arm, else_arm].into(),
4513+
hir::MatchSource::WhileDesugar,
4514+
);
4515+
4516+
hir::ExprKind::Loop(
4517+
P(this.block_expr(P(match_expr))),
44834518
this.lower_label(opt_label),
4519+
hir::LoopSource::While,
44844520
)
44854521
})
44864522
}

src/librustc/hir/map/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ impl<'hir> Map<'hir> {
735735
match *node {
736736
Node::Expr(ref expr) => {
737737
match expr.node {
738-
ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Ret(..) => true,
738+
ExprKind::Loop(..) | ExprKind::Ret(..) => true,
739739
_ => false,
740740
}
741741
}

src/librustc/hir/mod.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,6 @@ impl Expr {
14041404
ExprKind::Lit(_) => ExprPrecedence::Lit,
14051405
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
14061406
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
1407-
ExprKind::While(..) => ExprPrecedence::While,
14081407
ExprKind::Loop(..) => ExprPrecedence::Loop,
14091408
ExprKind::Match(..) => ExprPrecedence::Match,
14101409
ExprKind::Closure(..) => ExprPrecedence::Closure,
@@ -1463,7 +1462,6 @@ impl Expr {
14631462
ExprKind::Break(..) |
14641463
ExprKind::Continue(..) |
14651464
ExprKind::Ret(..) |
1466-
ExprKind::While(..) |
14671465
ExprKind::Loop(..) |
14681466
ExprKind::Assign(..) |
14691467
ExprKind::InlineAsm(..) |
@@ -1531,10 +1529,6 @@ pub enum ExprKind {
15311529
/// This construct only exists to tweak the drop order in HIR lowering.
15321530
/// An example of that is the desugaring of `for` loops.
15331531
DropTemps(P<Expr>),
1534-
/// A while loop, with an optional label
1535-
///
1536-
/// I.e., `'label: while expr { <block> }`.
1537-
While(P<Expr>, P<Block>, Option<Label>),
15381532
/// A conditionless loop (can be exited with `break`, `continue`, or `return`).
15391533
///
15401534
/// I.e., `'label: loop { <block> }`.
@@ -1652,6 +1646,8 @@ pub enum MatchSource {
16521646
IfLetDesugar {
16531647
contains_else_clause: bool,
16541648
},
1649+
/// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`).
1650+
WhileDesugar,
16551651
/// A `while let _ = _ { .. }` (which was desugared to a
16561652
/// `loop { match _ { .. } }`).
16571653
WhileLetDesugar,
@@ -1668,12 +1664,25 @@ pub enum MatchSource {
16681664
pub enum LoopSource {
16691665
/// A `loop { .. }` loop.
16701666
Loop,
1667+
/// A `while _ { .. }` loop.
1668+
While,
16711669
/// A `while let _ = _ { .. }` loop.
16721670
WhileLet,
16731671
/// A `for _ in _ { .. }` loop.
16741672
ForLoop,
16751673
}
16761674

1675+
impl LoopSource {
1676+
pub fn name(self) -> &'static str {
1677+
match self {
1678+
LoopSource::Loop => "loop",
1679+
LoopSource::While => "while",
1680+
LoopSource::WhileLet => "while let",
1681+
LoopSource::ForLoop => "for",
1682+
}
1683+
}
1684+
}
1685+
16771686
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
16781687
pub enum LoopIdError {
16791688
OutsideLoopScope,

src/librustc/hir/print.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,16 +1322,6 @@ impl<'a> State<'a> {
13221322
// Print `}`:
13231323
self.bclose_maybe_open(expr.span, indent_unit, true)?;
13241324
}
1325-
hir::ExprKind::While(ref test, ref blk, opt_label) => {
1326-
if let Some(label) = opt_label {
1327-
self.print_ident(label.ident)?;
1328-
self.word_space(":")?;
1329-
}
1330-
self.head("while")?;
1331-
self.print_expr_as_cond(&test)?;
1332-
self.s.space()?;
1333-
self.print_block(&blk)?;
1334-
}
13351325
hir::ExprKind::Loop(ref blk, opt_label, _) => {
13361326
if let Some(label) = opt_label {
13371327
self.print_ident(label.ident)?;
@@ -2329,7 +2319,6 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
23292319
match e.node {
23302320
hir::ExprKind::Match(..) |
23312321
hir::ExprKind::Block(..) |
2332-
hir::ExprKind::While(..) |
23332322
hir::ExprKind::Loop(..) => false,
23342323
_ => true,
23352324
}

src/librustc/middle/expr_use_visitor.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -487,11 +487,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
487487
self.walk_block(&blk);
488488
}
489489

490-
hir::ExprKind::While(ref cond_expr, ref blk, _) => {
491-
self.consume_expr(&cond_expr);
492-
self.walk_block(&blk);
493-
}
494-
495490
hir::ExprKind::Unary(_, ref lhs) => {
496491
self.consume_expr(&lhs);
497492
}

src/librustc/middle/liveness.rs

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393
//! It is the responsibility of typeck to ensure that there are no
9494
//! `return` expressions in a function declared as diverging.
9595
96-
use self::LoopKind::*;
9796
use self::LiveNodeKind::*;
9897
use self::VarKind::*;
9998

@@ -120,14 +119,6 @@ use crate::hir::{Expr, HirId};
120119
use crate::hir::def_id::DefId;
121120
use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
122121

123-
/// For use with `propagate_through_loop`.
124-
enum LoopKind<'a> {
125-
/// An endless `loop` loop.
126-
LoopLoop,
127-
/// A `while` loop, with the given expression as condition.
128-
WhileLoop(&'a Expr),
129-
}
130-
131122
#[derive(Copy, Clone, PartialEq)]
132123
struct Variable(u32);
133124

@@ -517,7 +508,6 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) {
517508

518509
// live nodes required for interesting control flow:
519510
hir::ExprKind::Match(..) |
520-
hir::ExprKind::While(..) |
521511
hir::ExprKind::Loop(..) => {
522512
ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
523513
intravisit::walk_expr(ir, expr);
@@ -1055,14 +1045,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10551045
})
10561046
}
10571047

1058-
hir::ExprKind::While(ref cond, ref blk, _) => {
1059-
self.propagate_through_loop(expr, WhileLoop(&cond), &blk, succ)
1060-
}
1061-
10621048
// Note that labels have been resolved, so we don't need to look
10631049
// at the label ident
10641050
hir::ExprKind::Loop(ref blk, _, _) => {
1065-
self.propagate_through_loop(expr, LoopLoop, &blk, succ)
1051+
self.propagate_through_loop(expr, &blk, succ)
10661052
}
10671053

10681054
hir::ExprKind::Match(ref e, ref arms, _) => {
@@ -1353,13 +1339,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
13531339
}
13541340
}
13551341

1356-
fn propagate_through_loop(&mut self,
1357-
expr: &Expr,
1358-
kind: LoopKind<'_>,
1359-
body: &hir::Block,
1360-
succ: LiveNode)
1361-
-> LiveNode {
1342+
fn propagate_through_loop(
1343+
&mut self,
1344+
expr: &Expr,
1345+
body: &hir::Block,
1346+
succ: LiveNode
1347+
) -> LiveNode {
13621348
/*
1349+
FIXME: clean up this description.
13631350
13641351
We model control flow like this:
13651352
@@ -1377,50 +1364,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
13771364
13781365
*/
13791366

1380-
13811367
// first iteration:
13821368
let mut first_merge = true;
13831369
let ln = self.live_node(expr.hir_id, expr.span);
13841370
self.init_empty(ln, succ);
1385-
match kind {
1386-
LoopLoop => {}
1387-
_ => {
1388-
// If this is not a `loop` loop, then it's possible we bypass
1389-
// the body altogether. Otherwise, the only way is via a `break`
1390-
// in the loop body.
1391-
self.merge_from_succ(ln, succ, first_merge);
1392-
first_merge = false;
1393-
}
1394-
}
13951371
debug!("propagate_through_loop: using id for loop body {} {}",
13961372
expr.hir_id, self.ir.tcx.hir().hir_to_pretty_string(body.hir_id));
13971373

13981374
self.break_ln.insert(expr.hir_id, succ);
13991375

1400-
let cond_ln = match kind {
1401-
LoopLoop => ln,
1402-
WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln),
1403-
};
1404-
1405-
self.cont_ln.insert(expr.hir_id, cond_ln);
1376+
self.cont_ln.insert(expr.hir_id, ln);
14061377

1407-
let body_ln = self.propagate_through_block(body, cond_ln);
1378+
let body_ln = self.propagate_through_block(body, ln);
14081379

14091380
// repeat until fixed point is reached:
14101381
while self.merge_from_succ(ln, body_ln, first_merge) {
14111382
first_merge = false;
1412-
1413-
let new_cond_ln = match kind {
1414-
LoopLoop => ln,
1415-
WhileLoop(ref cond) => {
1416-
self.propagate_through_expr(&cond, ln)
1417-
}
1418-
};
1419-
assert_eq!(cond_ln, new_cond_ln);
1420-
assert_eq!(body_ln, self.propagate_through_block(body, cond_ln));
1383+
assert_eq!(body_ln, self.propagate_through_block(body, ln));
14211384
}
14221385

1423-
cond_ln
1386+
ln
14241387
}
14251388
}
14261389

@@ -1520,7 +1483,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
15201483

15211484
// no correctness conditions related to liveness
15221485
hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) |
1523-
hir::ExprKind::Match(..) | hir::ExprKind::While(..) | hir::ExprKind::Loop(..) |
1486+
hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) |
15241487
hir::ExprKind::Index(..) | hir::ExprKind::Field(..) |
15251488
hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) | hir::ExprKind::Binary(..) |
15261489
hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) | hir::ExprKind::Unary(..) |

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
694694
hir::ExprKind::Unary(..) | hir::ExprKind::Yield(..) |
695695
hir::ExprKind::MethodCall(..) | hir::ExprKind::Cast(..) | hir::ExprKind::DropTemps(..) |
696696
hir::ExprKind::Array(..) | hir::ExprKind::Tup(..) |
697-
hir::ExprKind::Binary(..) | hir::ExprKind::While(..) |
697+
hir::ExprKind::Binary(..) |
698698
hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
699699
hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
700700
hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |

src/librustc/middle/region.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -915,11 +915,6 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
915915
terminating(body.hir_id.local_id);
916916
}
917917

918-
hir::ExprKind::While(ref expr, ref body, _) => {
919-
terminating(expr.hir_id.local_id);
920-
terminating(body.hir_id.local_id);
921-
}
922-
923918
hir::ExprKind::DropTemps(ref expr) => {
924919
// `DropTemps(expr)` does not denote a conditional scope.
925920
// Rather, we want to achieve the same behavior as `{ let _t = expr; _t }`.

0 commit comments

Comments
 (0)