Skip to content

Commit 832d7e0

Browse files
committed
Add TerminatorKind::if_ convenience constructor
Constructs a TerminatorKind::SwitchInt for an equivalent conditional true-false branch.
1 parent 1fee722 commit 832d7e0

File tree

5 files changed

+38
-62
lines changed

5 files changed

+38
-62
lines changed

src/librustc/mir/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,6 @@ pub struct Terminator<'tcx> {
446446
pub kind: TerminatorKind<'tcx>
447447
}
448448

449-
/// For use in SwitchInt, for switching on bools.
450-
pub static BOOL_SWITCH_FALSE: Cow<'static, [ConstInt]> = Cow::Borrowed(&[ConstInt::Infer(0)]);
451-
452449
#[derive(Clone, RustcEncodable, RustcDecodable)]
453450
pub enum TerminatorKind<'tcx> {
454451
/// block should have one successor in the graph; we jump there
@@ -543,6 +540,17 @@ impl<'tcx> Terminator<'tcx> {
543540
}
544541

545542
impl<'tcx> TerminatorKind<'tcx> {
543+
pub fn if_<'a, 'gcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>,
544+
t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
545+
static BOOL_SWITCH_FALSE: &'static [ConstInt] = &[ConstInt::Infer(0)];
546+
TerminatorKind::SwitchInt {
547+
discr: cond,
548+
switch_ty: tcx.types.bool,
549+
values: From::from(BOOL_SWITCH_FALSE),
550+
targets: vec![f, t],
551+
}
552+
}
553+
546554
pub fn successors(&self) -> Cow<[BasicBlock]> {
547555
use self::TerminatorKind::*;
548556
match *self {

src/librustc_borrowck/borrowck/mir/elaborate_drops.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,8 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
842842
(true, false) => on_set,
843843
(true, true) => {
844844
let flag = self.drop_flag(c.path).unwrap();
845-
let boolty = self.tcx.types.bool;
846-
self.new_block(c, is_cleanup, TerminatorKind::SwitchInt {
847-
discr: Operand::Consume(flag),
848-
switch_ty: boolty,
849-
values: BOOL_SWITCH_FALSE.clone(),
850-
targets: vec![on_unset, on_set],
851-
})
845+
let term = TerminatorKind::if_(self.tcx, Operand::Consume(flag), on_set, on_unset);
846+
self.new_block(c, is_cleanup, term)
852847
}
853848
}
854849
}

src/librustc_mir/build/expr/into.rs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6969

7070
let mut then_block = this.cfg.start_new_block();
7171
let mut else_block = this.cfg.start_new_block();
72-
this.cfg.terminate(block, source_info, TerminatorKind::SwitchInt {
73-
discr: operand,
74-
switch_ty: this.hir.bool_ty(),
75-
values: BOOL_SWITCH_FALSE.clone(),
76-
targets: vec![else_block, then_block],
77-
});
72+
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
73+
this.cfg.terminate(block, source_info, term);
7874

7975
unpack!(then_block = this.into(destination, then_block, then_expr));
8076
else_block = if let Some(else_expr) = else_expr {
@@ -113,23 +109,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
113109

114110
let lhs = unpack!(block = this.as_operand(block, lhs));
115111
let blocks = match op {
116-
LogicalOp::And => vec![false_block, else_block],
117-
LogicalOp::Or => vec![else_block, true_block],
112+
LogicalOp::And => (else_block, false_block),
113+
LogicalOp::Or => (true_block, else_block),
118114
};
119-
this.cfg.terminate(block, source_info, TerminatorKind::SwitchInt {
120-
discr: lhs,
121-
switch_ty: this.hir.bool_ty(),
122-
values: BOOL_SWITCH_FALSE.clone(),
123-
targets: blocks,
124-
});
115+
let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1);
116+
this.cfg.terminate(block, source_info, term);
125117

126118
let rhs = unpack!(else_block = this.as_operand(else_block, rhs));
127-
this.cfg.terminate(else_block, source_info, TerminatorKind::SwitchInt {
128-
discr: rhs,
129-
switch_ty: this.hir.bool_ty(),
130-
values: BOOL_SWITCH_FALSE.clone(),
131-
targets: vec![false_block, true_block],
132-
});
119+
let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block);
120+
this.cfg.terminate(else_block, source_info, term);
133121

134122
this.cfg.push_assign_constant(
135123
true_block, source_info, destination,
@@ -187,13 +175,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
187175
let cond = unpack!(
188176
loop_block_end = this.as_operand(loop_block, cond_expr));
189177
body_block = this.cfg.start_new_block();
190-
this.cfg.terminate(loop_block_end, source_info,
191-
TerminatorKind::SwitchInt {
192-
discr: cond,
193-
switch_ty: this.hir.bool_ty(),
194-
values: BOOL_SWITCH_FALSE.clone(),
195-
targets: vec![exit_block, body_block],
196-
});
178+
let term = TerminatorKind::if_(this.hir.tcx(), cond,
179+
body_block, exit_block);
180+
this.cfg.terminate(loop_block_end, source_info, term);
197181

198182
// if the test is false, there's no `break` to assign `destination`, so
199183
// we have to do it; this overwrites any `break`-assigned value but it's

src/librustc_mir/build/matches/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -672,12 +672,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
672672
let source_info = self.source_info(guard.span);
673673
let cond = unpack!(block = self.as_operand(block, guard));
674674
let otherwise = self.cfg.start_new_block();
675-
self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt {
676-
discr: cond,
677-
switch_ty: self.hir.bool_ty(),
678-
values: BOOL_SWITCH_FALSE.clone(),
679-
targets: vec![otherwise, arm_block],
680-
});
675+
self.cfg.terminate(block, source_info,
676+
TerminatorKind::if_(self.hir.tcx(), cond, arm_block, otherwise));
681677
Some(otherwise)
682678
} else {
683679
let source_info = self.source_info(candidate.span);

src/librustc_mir/build/matches/test.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
228228

229229
TestKind::SwitchInt { switch_ty, ref options, indices: _ } => {
230230
let (values, targets, ret) = if switch_ty.sty == ty::TyBool {
231+
static BOOL_SWITCH_FALSE: &'static [ConstInt] = &[ConstInt::Infer(0)];
231232
assert!(options.len() > 0 && options.len() <= 2);
232233
let (true_bb, false_bb) = (self.cfg.start_new_block(),
233234
self.cfg.start_new_block());
@@ -236,7 +237,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
236237
&ConstVal::Bool(false) => vec![false_bb, true_bb],
237238
v => span_bug!(test.span, "expected boolean value but got {:?}", v)
238239
};
239-
(BOOL_SWITCH_FALSE.clone(), vec![false_bb, true_bb], ret)
240+
(From::from(BOOL_SWITCH_FALSE), vec![false_bb, true_bb], ret)
240241
} else {
241242
// The switch may be inexhaustive so we
242243
// add a catch all block
@@ -323,12 +324,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
323324

324325
// check the result
325326
let block = self.cfg.start_new_block();
326-
self.cfg.terminate(eq_block, source_info, TerminatorKind::SwitchInt {
327-
discr: Operand::Consume(eq_result),
328-
switch_ty: self.hir.bool_ty(),
329-
values: BOOL_SWITCH_FALSE.clone(),
330-
targets: vec![fail, block],
331-
});
327+
self.cfg.terminate(eq_block, source_info,
328+
TerminatorKind::if_(self.hir.tcx(),
329+
Operand::Consume(eq_result),
330+
block, fail));
332331
vec![block, fail]
333332
} else {
334333
let block = self.compare(block, fail, test.span, BinOp::Eq, expect, val);
@@ -372,12 +371,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
372371
// branch based on result
373372
let (false_bb, true_bb) = (self.cfg.start_new_block(),
374373
self.cfg.start_new_block());
375-
self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt {
376-
discr: Operand::Consume(result),
377-
switch_ty: self.hir.bool_ty(),
378-
values: BOOL_SWITCH_FALSE.clone(),
379-
targets: vec![false_bb, true_bb],
380-
});
374+
self.cfg.terminate(block, source_info,
375+
TerminatorKind::if_(self.hir.tcx(), Operand::Consume(result),
376+
true_bb, false_bb));
381377
vec![true_bb, false_bb]
382378
}
383379
}
@@ -400,12 +396,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
400396

401397
// branch based on result
402398
let target_block = self.cfg.start_new_block();
403-
self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt {
404-
discr: Operand::Consume(result),
405-
switch_ty: self.hir.bool_ty(),
406-
values: BOOL_SWITCH_FALSE.clone(),
407-
targets: vec![fail_block, target_block]
408-
});
399+
self.cfg.terminate(block, source_info,
400+
TerminatorKind::if_(self.hir.tcx(), Operand::Consume(result),
401+
target_block, fail_block));
409402
target_block
410403
}
411404

0 commit comments

Comments
 (0)