pub is_cleanup: bool,
}
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+pub struct Terminator<'tcx> {
+ pub kind: TerminatorKind<'tcx>
+}
+
#[derive(Clone, RustcEncodable, RustcDecodable)]
-pub enum Terminator<'tcx> {
+pub enum TerminatorKind<'tcx> {
/// block should have one successor in the graph; we jump there
Goto {
target: BasicBlock,
impl<'tcx> Terminator<'tcx> {
pub fn successors(&self) -> Cow<[BasicBlock]> {
- use self::Terminator::*;
+ self.kind.successors()
+ }
+
+ pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
+ self.kind.successors_mut()
+ }
+}
+
+impl<'tcx> TerminatorKind<'tcx> {
+ pub fn successors(&self) -> Cow<[BasicBlock]> {
+ use self::TerminatorKind::*;
match *self {
Goto { target: ref b } => slice::ref_slice(b).into_cow(),
If { targets: (b1, b2), .. } => vec![b1, b2].into_cow(),
// FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
// `Vec<&mut BasicBlock>` would look like in the first place.
pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
- use self::Terminator::*;
+ use self::TerminatorKind::*;
match *self {
Goto { target: ref mut b } => vec![b],
If { targets: (ref mut b1, ref mut b2), .. } => vec![b1, b2],
}
}
-impl<'tcx> Debug for Terminator<'tcx> {
+impl<'tcx> Debug for TerminatorKind<'tcx> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.fmt_head(fmt)?;
let successors = self.successors();
}
}
-impl<'tcx> Terminator<'tcx> {
+impl<'tcx> TerminatorKind<'tcx> {
/// Write the "head" part of the terminator; that is, its name and the data it uses to pick the
/// successor basic block, if any. The only information not inlcuded is the list of possible
/// successors, which may be rendered differently between the text and the graphviz format.
pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
- use self::Terminator::*;
+ use self::TerminatorKind::*;
match *self {
Goto { .. } => write!(fmt, "goto"),
If { cond: ref lv, .. } => write!(fmt, "if({:?})", lv),
/// Return the list of labels for the edges to the successor basic blocks.
pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
- use self::Terminator::*;
+ use self::TerminatorKind::*;
match *self {
Return | Resume => vec![],
Goto { .. } => vec!["".into()],
fn super_terminator(&mut self,
block: BasicBlock,
terminator: &$($mutability)* Terminator<'tcx>) {
- match *terminator {
- Terminator::Goto { target } => {
+ match terminator.kind {
+ TerminatorKind::Goto { target } => {
self.visit_branch(block, target);
}
- Terminator::If { ref $($mutability)* cond,
- ref $($mutability)* targets } => {
+ TerminatorKind::If { ref $($mutability)* cond,
+ ref $($mutability)* targets } => {
self.visit_operand(cond);
for &target in targets.as_slice() {
self.visit_branch(block, target);
}
}
- Terminator::Switch { ref $($mutability)* discr,
- adt_def: _,
- ref targets } => {
+ TerminatorKind::Switch { ref $($mutability)* discr,
+ adt_def: _,
+ ref targets } => {
self.visit_lvalue(discr, LvalueContext::Inspect);
for &target in targets {
self.visit_branch(block, target);
}
}
- Terminator::SwitchInt { ref $($mutability)* discr,
- switch_ty: _,
- values: _,
- ref targets } => {
+ TerminatorKind::SwitchInt { ref $($mutability)* discr,
+ switch_ty: _,
+ values: _,
+ ref targets } => {
self.visit_lvalue(discr, LvalueContext::Inspect);
for &target in targets {
self.visit_branch(block, target);
}
}
- Terminator::Resume |
- Terminator::Return => {
+ TerminatorKind::Resume |
+ TerminatorKind::Return => {
}
- Terminator::Drop { ref $($mutability)* value, target, unwind } => {
+ TerminatorKind::Drop { ref $($mutability)* value,
+ target,
+ unwind } => {
self.visit_lvalue(value, LvalueContext::Drop);
self.visit_branch(block, target);
unwind.map(|t| self.visit_branch(block, t));
}
- Terminator::Call { ref $($mutability)* func,
- ref $($mutability)* args,
- ref $($mutability)* destination,
- cleanup } => {
+ TerminatorKind::Call { ref $($mutability)* func,
+ ref $($mutability)* args,
+ ref $($mutability)* destination,
+ cleanup } => {
self.visit_operand(func);
for arg in args {
self.visit_operand(arg);
bb: &repr::BasicBlockData,
on_return: OnReturn) where OnReturn: Fn(&D, &mut [usize], &repr::Lvalue)
{
- let term = if let Some(ref term) = bb.terminator { term } else { return };
- match *term {
- repr::Terminator::Return |
- repr::Terminator::Resume => {}
- repr::Terminator::Goto { ref target } |
- repr::Terminator::Drop { ref target, value: _, unwind: None } => {
+ match bb.terminator().kind {
+ repr::TerminatorKind::Return |
+ repr::TerminatorKind::Resume => {}
+ repr::TerminatorKind::Goto { ref target } |
+ repr::TerminatorKind::Drop { ref target, value: _, unwind: None } => {
self.propagate_bits_into_entry_set_for(in_out, changed, target);
}
- repr::Terminator::Drop { ref target, value: _, unwind: Some(ref unwind) } => {
+ repr::TerminatorKind::Drop { ref target, value: _, unwind: Some(ref unwind) } => {
self.propagate_bits_into_entry_set_for(in_out, changed, target);
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
}
- repr::Terminator::If { ref targets, .. } => {
+ repr::TerminatorKind::If { ref targets, .. } => {
self.propagate_bits_into_entry_set_for(in_out, changed, &targets.0);
self.propagate_bits_into_entry_set_for(in_out, changed, &targets.1);
}
- repr::Terminator::Switch { ref targets, .. } |
- repr::Terminator::SwitchInt { ref targets, .. } => {
+ repr::TerminatorKind::Switch { ref targets, .. } |
+ repr::TerminatorKind::SwitchInt { ref targets, .. } => {
for target in targets {
self.propagate_bits_into_entry_set_for(in_out, changed, target);
}
}
- repr::Terminator::Call { ref cleanup, ref destination, func: _, args: _ } => {
+ repr::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
if let Some(ref unwind) = *cleanup {
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
}
use rustc::middle::ty;
use rustc::mir::repr::{self, Mir, BasicBlock, Lvalue, Rvalue};
-use rustc::mir::repr::{StatementKind, Terminator};
+use rustc::mir::repr::{StatementKind, TerminatorKind};
use rustc::util::nodemap::FnvHashMap;
use std::cell::{Cell};
}
}
- if let Some(ref term) = bb_data.terminator {
- match *term {
- Terminator::Goto { target: _ } | Terminator::Resume => { }
+ match bb_data.terminator().kind {
+ TerminatorKind::Goto { target: _ } | TerminatorKind::Resume => { }
- Terminator::Return => {
- let source = Location { block: bb,
- index: bb_data.statements.len() };
- let lval = &Lvalue::ReturnPointer.deref();
- bb_ctxt.on_move_out_lval(SK::Return, lval, source);
- }
+ TerminatorKind::Return => {
+ let source = Location { block: bb,
+ index: bb_data.statements.len() };
+ let lval = &Lvalue::ReturnPointer.deref();
+ bb_ctxt.on_move_out_lval(SK::Return, lval, source);
+ }
- Terminator::If { ref cond, targets: _ } => {
- // The `cond` is always of (copyable) type `bool`,
- // so there will never be anything to move.
- let _ = cond;
- }
+ TerminatorKind::If { ref cond, targets: _ } => {
+ // The `cond` is always of (copyable) type `bool`,
+ // so there will never be anything to move.
+ let _ = cond;
+ }
- Terminator::SwitchInt { switch_ty: _, values: _, targets: _, ref discr } |
- Terminator::Switch { adt_def: _, targets: _, ref discr } => {
- // The `discr` is not consumed; that is instead
- // encoded on specific match arms (and for
- // SwitchInt`, it is always a copyable integer
- // type anyway).
- let _ = discr;
- }
+ TerminatorKind::SwitchInt { switch_ty: _, values: _, targets: _, ref discr } |
+ TerminatorKind::Switch { adt_def: _, targets: _, ref discr } => {
+ // The `discr` is not consumed; that is instead
+ // encoded on specific match arms (and for
+ // SwitchInt`, it is always a copyable integer
+ // type anyway).
+ let _ = discr;
+ }
- Terminator::Drop { value: ref lval, target: _, unwind: _ } => {
- let source = Location { block: bb,
- index: bb_data.statements.len() };
- bb_ctxt.on_move_out_lval(SK::Drop, lval, source);
- }
+ TerminatorKind::Drop { value: ref lval, target: _, unwind: _ } => {
+ let source = Location { block: bb,
+ index: bb_data.statements.len() };
+ bb_ctxt.on_move_out_lval(SK::Drop, lval, source);
+ }
- Terminator::Call { ref func, ref args, ref destination, cleanup: _ } => {
- let source = Location { block: bb,
- index: bb_data.statements.len() };
- bb_ctxt.on_operand(SK::CallFn, func, source);
- for arg in args {
- bb_ctxt.on_operand(SK::CallArg, arg, source);
- }
- if let Some((ref destination, _bb)) = *destination {
- // Create MovePath for `destination`, then
- // discard returned index.
- bb_ctxt.builder.move_path_for(destination);
- }
+ TerminatorKind::Call { ref func, ref args, ref destination, cleanup: _ } => {
+ let source = Location { block: bb,
+ index: bb_data.statements.len() };
+ bb_ctxt.on_operand(SK::CallFn, func, source);
+ for arg in args {
+ bb_ctxt.on_operand(SK::CallArg, arg, source);
+ }
+ if let Some((ref destination, _bb)) = *destination {
+ // Create MovePath for `destination`, then
+ // discard returned index.
+ bb_ctxt.builder.move_path_for(destination);
}
}
}
pub fn terminate(&mut self,
block: BasicBlock,
- terminator: Terminator<'tcx>) {
+ kind: TerminatorKind<'tcx>) {
debug_assert!(self.block_data(block).terminator.is_none(),
"terminate: block {:?} already has a terminator set", block);
- self.block_data_mut(block).terminator = Some(terminator);
+ self.block_data_mut(block).terminator = Some(Terminator {
+ kind: kind
+ });
}
}
let (success, failure) = (this.cfg.start_new_block(), this.cfg.start_new_block());
this.cfg.terminate(block,
- Terminator::If {
+ TerminatorKind::If {
cond: Operand::Consume(lt),
targets: (success, failure),
});
let mut then_block = this.cfg.start_new_block();
let mut else_block = this.cfg.start_new_block();
- this.cfg.terminate(block, Terminator::If {
+ this.cfg.terminate(block, TerminatorKind::If {
cond: operand,
targets: (then_block, else_block)
});
};
let join_block = this.cfg.start_new_block();
- this.cfg.terminate(then_block, Terminator::Goto { target: join_block });
- this.cfg.terminate(else_block, Terminator::Goto { target: join_block });
+ this.cfg.terminate(then_block, TerminatorKind::Goto { target: join_block });
+ this.cfg.terminate(else_block, TerminatorKind::Goto { target: join_block });
join_block.unit()
}
LogicalOp::And => (else_block, false_block),
LogicalOp::Or => (true_block, else_block),
};
- this.cfg.terminate(block, Terminator::If { cond: lhs, targets: blocks });
+ this.cfg.terminate(block, TerminatorKind::If { cond: lhs, targets: blocks });
let rhs = unpack!(else_block = this.as_operand(else_block, rhs));
- this.cfg.terminate(else_block, Terminator::If {
+ this.cfg.terminate(else_block, TerminatorKind::If {
cond: rhs,
targets: (true_block, false_block)
});
literal: this.hir.false_literal(),
});
- this.cfg.terminate(true_block, Terminator::Goto { target: join_block });
- this.cfg.terminate(false_block, Terminator::Goto { target: join_block });
+ this.cfg.terminate(true_block, TerminatorKind::Goto { target: join_block });
+ this.cfg.terminate(false_block, TerminatorKind::Goto { target: join_block });
join_block.unit()
}
let exit_block = this.cfg.start_new_block();
// start the loop
- this.cfg.terminate(block, Terminator::Goto { target: loop_block });
+ this.cfg.terminate(block, TerminatorKind::Goto { target: loop_block });
let might_break = this.in_loop_scope(loop_block, exit_block, move |this| {
// conduct the test, if necessary
let cond = unpack!(loop_block_end = this.as_operand(loop_block, cond_expr));
body_block = this.cfg.start_new_block();
this.cfg.terminate(loop_block_end,
- Terminator::If {
+ TerminatorKind::If {
cond: cond,
targets: (body_block, exit_block)
});
let tmp = this.get_unit_temp();
// Execute the body, branching back to the test.
let body_block_end = unpack!(this.into(&tmp, body_block, body));
- this.cfg.terminate(body_block_end, Terminator::Goto { target: loop_block });
+ this.cfg.terminate(body_block_end, TerminatorKind::Goto { target: loop_block });
});
// If the loop may reach its exit_block, we assign an empty tuple to the
// destination to keep the MIR well-formed.
let success = this.cfg.start_new_block();
let cleanup = this.diverge_cleanup();
- this.cfg.terminate(block, Terminator::Call {
+ this.cfg.terminate(block, TerminatorKind::Call {
func: fun,
args: args,
cleanup: cleanup,
for (arm_index, arm_body) in arm_bodies.into_iter().enumerate() {
let mut arm_block = arm_blocks.blocks[arm_index];
unpack!(arm_block = self.into(destination, arm_block, arm_body));
- self.cfg.terminate(arm_block, Terminator::Goto { target: end_block });
+ self.cfg.terminate(arm_block, TerminatorKind::Goto { target: end_block });
}
end_block.unit()
} else {
let join_block = self.cfg.start_new_block();
for block in otherwise {
- self.cfg.terminate(block, Terminator::Goto { target: join_block });
+ self.cfg.terminate(block, TerminatorKind::Goto { target: join_block });
}
join_block
}
// guard, this block is simply unreachable
let cond = unpack!(block = self.as_operand(block, guard));
let otherwise = self.cfg.start_new_block();
- self.cfg.terminate(block, Terminator::If { cond: cond,
+ self.cfg.terminate(block, TerminatorKind::If { cond: cond,
targets: (arm_block, otherwise)});
Some(otherwise)
} else {
- self.cfg.terminate(block, Terminator::Goto { target: arm_block });
+ self.cfg.terminate(block, TerminatorKind::Goto { target: arm_block });
None
}
}
let target_blocks: Vec<_> =
(0..num_enum_variants).map(|_| self.cfg.start_new_block())
.collect();
- self.cfg.terminate(block, Terminator::Switch {
+ self.cfg.terminate(block, TerminatorKind::Switch {
discr: lvalue.clone(),
adt_def: adt_def,
targets: target_blocks.clone()
.map(|_| self.cfg.start_new_block())
.chain(Some(otherwise))
.collect();
- self.cfg.terminate(block, Terminator::SwitchInt {
+ self.cfg.terminate(block, TerminatorKind::SwitchInt {
discr: lvalue.clone(),
switch_ty: switch_ty,
values: options.clone(),
// branch based on result
let target_blocks: Vec<_> = vec![self.cfg.start_new_block(),
self.cfg.start_new_block()];
- self.cfg.terminate(block, Terminator::If {
+ self.cfg.terminate(block, TerminatorKind::If {
cond: Operand::Consume(result),
targets: (target_blocks[0], target_blocks[1])
});
// branch based on result
let target_block = self.cfg.start_new_block();
- self.cfg.terminate(block, Terminator::If {
+ self.cfg.terminate(block, TerminatorKind::If {
cond: Operand::Consume(result),
targets: (target_block, fail_block)
});
argument_extent,
ast_block));
- builder.cfg.terminate(block, Terminator::Goto { target: END_BLOCK });
- builder.cfg.terminate(END_BLOCK, Terminator::Return);
+ builder.cfg.terminate(block, TerminatorKind::Goto { target: END_BLOCK });
+ builder.cfg.terminate(END_BLOCK, TerminatorKind::Return);
MirPlusPlus {
mir: Mir {
.postdoms
.push(self.cfg.current_location(block));
}
- self.cfg.terminate(block, Terminator::Goto { target: target });
+ self.cfg.terminate(block, TerminatorKind::Goto { target: target });
}
// Finding scopes
pub fn build_drop(&mut self, block: BasicBlock, value: Lvalue<'tcx>) -> BlockAnd<()> {
let next_target = self.cfg.start_new_block();
let diverge_target = self.diverge_cleanup();
- self.cfg.terminate(block, Terminator::Drop {
+ self.cfg.terminate(block, TerminatorKind::Drop {
value: value,
target: next_target,
unwind: diverge_target,
self.cfg.push_assign(block, scope_id, span, &tuple_ref, // tuple_ref = &tuple;
Rvalue::Ref(region, BorrowKind::Shared, tuple));
let cleanup = self.diverge_cleanup();
- self.cfg.terminate(block, Terminator::Call {
+ self.cfg.terminate(block, TerminatorKind::Call {
func: Operand::Constant(func),
args: vec![Operand::Consume(tuple_ref), index, len],
destination: None,
self.cfg.push_assign(block, scope_id, span, &tuple_ref, // tuple_ref = &tuple;
Rvalue::Ref(region, BorrowKind::Shared, tuple));
let cleanup = self.diverge_cleanup();
- self.cfg.terminate(block, Terminator::Call {
+ self.cfg.terminate(block, TerminatorKind::Call {
func: Operand::Constant(func),
args: vec![Operand::Consume(tuple_ref)],
cleanup: cleanup,
earlier_scopes.iter().rev().flat_map(|s| s.cached_block()).next()
});
let next = cfg.start_new_block();
- cfg.terminate(block, Terminator::Drop {
+ cfg.terminate(block, TerminatorKind::Drop {
value: drop_data.value.clone(),
target: next,
unwind: on_diverge
for drop_data in scope.drops.iter_mut().rev() {
if let Some(cached_block) = drop_data.cached_block {
if let Some((previous_block, previous_value)) = previous {
- cfg.terminate(previous_block, Terminator::Drop {
+ cfg.terminate(previous_block, TerminatorKind::Drop {
value: previous_value,
target: cached_block,
unwind: None
let block = cfg.start_new_cleanup_block();
drop_data.cached_block = Some(block);
if let Some((previous_block, previous_value)) = previous {
- cfg.terminate(previous_block, Terminator::Drop {
+ cfg.terminate(previous_block, TerminatorKind::Drop {
value: previous_value,
target: block,
unwind: None
// Prepare the end target for this chain.
let mut target = target.unwrap_or_else(||{
let b = cfg.start_new_cleanup_block();
- cfg.terminate(b, Terminator::Resume);
+ cfg.terminate(b, TerminatorKind::Resume);
b
});
if let Some((previous_block, previous_value)) = previous {
// Finally, branch into that just-built `target` from the `previous_block`.
- cfg.terminate(previous_block, Terminator::Drop {
+ cfg.terminate(previous_block, TerminatorKind::Drop {
value: previous_value,
target: target,
unwind: None
fn build_free<'tcx>(tcx: &TyCtxt<'tcx>,
unit_temp: Lvalue<'tcx>,
data: &FreeData<'tcx>,
- target: BasicBlock) -> Terminator<'tcx> {
+ target: BasicBlock)
+ -> TerminatorKind<'tcx> {
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.unwrap_or_else(|e| tcx.sess.fatal(&e));
let substs = tcx.mk_substs(Substs::new(
VecPerParamSpace::new(vec![], vec![], vec![data.item_ty]),
VecPerParamSpace::new(vec![], vec![], vec![])
));
- Terminator::Call {
+ TerminatorKind::Call {
func: Operand::Constant(Constant {
span: data.span,
ty: tcx.lookup_item_type(free_func).ty.subst(tcx, substs),
// Terminator head at the bottom, not including the list of successor blocks. Those will be
// displayed as labels on the edges between blocks.
let mut terminator_head = String::new();
- data.terminator().fmt_head(&mut terminator_head).unwrap();
+ data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
write!(w, r#"<tr><td align="left">{}</td></tr>"#, dot::escape_html(&terminator_head))?;
fini(w)?;
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> {
let terminator = &mir.basic_block_data(source).terminator();
- let labels = terminator.fmt_successor_labels();
+ let labels = terminator.kind.fmt_successor_labels();
for (&target, label) in terminator.successors().iter().zip(labels) {
writeln!(w, r#" {} -> {} [label="{}"];"#, node(source), node(target), label)?;
}
fn visit_terminator(&mut self, bb: BasicBlock, terminator: &mut Terminator<'tcx>) {
- match *terminator {
- Terminator::Goto { .. } |
- Terminator::Resume |
- Terminator::Return |
- Terminator::If { .. } |
- Terminator::Switch { .. } |
- Terminator::Drop { .. } |
- Terminator::Call { .. } => {
+ match terminator.kind {
+ TerminatorKind::Goto { .. } |
+ TerminatorKind::Resume |
+ TerminatorKind::Return |
+ TerminatorKind::If { .. } |
+ TerminatorKind::Switch { .. } |
+ TerminatorKind::Drop { .. } |
+ TerminatorKind::Call { .. } => {
/* nothing to do */
},
- Terminator::SwitchInt { ref mut switch_ty, .. } => {
+ TerminatorKind::SwitchInt { ref mut switch_ty, .. } => {
*switch_ty = self.tcx.erase_regions(switch_ty);
},
}
impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
fn visit_terminator(&mut self, bb: BasicBlock, terminator: &mut Terminator<'tcx>) {
- match *terminator {
- Terminator::Goto { .. } |
- Terminator::Resume |
- Terminator::Return |
- Terminator::If { .. } |
- Terminator::Switch { .. } |
- Terminator::SwitchInt { .. } => {
+ match terminator.kind {
+ TerminatorKind::Goto { .. } |
+ TerminatorKind::Resume |
+ TerminatorKind::Return |
+ TerminatorKind::If { .. } |
+ TerminatorKind::Switch { .. } |
+ TerminatorKind::SwitchInt { .. } => {
/* nothing to do */
},
- Terminator::Drop { ref mut unwind, .. } => {
+ TerminatorKind::Drop { ref mut unwind, .. } => {
unwind.take();
},
- Terminator::Call { ref mut cleanup, .. } => {
+ TerminatorKind::Call { ref mut cleanup, .. } => {
cleanup.take();
},
}
let mut seen: Vec<BasicBlock> = Vec::with_capacity(8);
while mir.basic_block_data(target).statements.is_empty() {
- match mir.basic_block_data(target).terminator {
- Some(Terminator::Goto { target: next }) => {
+ match mir.basic_block_data(target).terminator().kind {
+ TerminatorKind::Goto { target: next } => {
if seen.contains(&next) {
return None;
}
for bb in mir.all_basic_blocks() {
let basic_block = mir.basic_block_data_mut(bb);
let mut terminator = basic_block.terminator_mut();
- *terminator = match *terminator {
- Terminator::If { ref targets, .. } if targets.0 == targets.1 => {
+ terminator.kind = match terminator.kind {
+ TerminatorKind::If { ref targets, .. } if targets.0 == targets.1 => {
changed = true;
- Terminator::Goto { target: targets.0 }
+ TerminatorKind::Goto { target: targets.0 }
}
- Terminator::If { ref targets, cond: Operand::Constant(Constant {
+ TerminatorKind::If { ref targets, cond: Operand::Constant(Constant {
literal: Literal::Value {
value: ConstVal::Bool(cond)
}, ..
}) } => {
changed = true;
if cond {
- Terminator::Goto { target: targets.0 }
+ TerminatorKind::Goto { target: targets.0 }
} else {
- Terminator::Goto { target: targets.1 }
+ TerminatorKind::Goto { target: targets.1 }
}
}
- Terminator::SwitchInt { ref targets, .. } if targets.len() == 1 => {
- Terminator::Goto { target: targets[0] }
+ TerminatorKind::SwitchInt { ref targets, .. } if targets.len() == 1 => {
+ TerminatorKind::Goto { target: targets[0] }
}
_ => continue
}
term: &Terminator<'tcx>) {
debug!("check_terminator: {:?}", term);
let tcx = self.tcx();
- match *term {
- Terminator::Goto { .. } |
- Terminator::Resume |
- Terminator::Return |
- Terminator::Drop { .. } => {
+ match term.kind {
+ TerminatorKind::Goto { .. } |
+ TerminatorKind::Resume |
+ TerminatorKind::Return |
+ TerminatorKind::Drop { .. } => {
// no checks needed for these
}
- Terminator::If { ref cond, .. } => {
+ TerminatorKind::If { ref cond, .. } => {
let cond_ty = mir.operand_ty(tcx, cond);
match cond_ty.sty {
ty::TyBool => {}
}
}
}
- Terminator::SwitchInt { ref discr, switch_ty, .. } => {
+ TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
let discr_ty = mir.lvalue_ty(tcx, discr).to_ty(tcx);
if let Err(terr) = self.mk_subty(self.last_span, discr_ty, switch_ty) {
span_mirbug!(self, term, "bad SwitchInt ({:?} on {:?}): {:?}",
}
// FIXME: check the values
}
- Terminator::Switch { ref discr, adt_def, ref targets } => {
+ TerminatorKind::Switch { ref discr, adt_def, ref targets } => {
let discr_ty = mir.lvalue_ty(tcx, discr).to_ty(tcx);
match discr_ty.sty {
ty::TyEnum(def, _)
}
}
}
- Terminator::Call { ref func, ref args, ref destination, .. } => {
+ TerminatorKind::Call { ref func, ref args, ref destination, .. } => {
let func_ty = mir.operand_ty(tcx, func);
debug!("check_terminator: call, func_ty={:?}", func_ty);
let func_ty = match func_ty.sty {
debug!("trans_block: terminator: {:?}", data.terminator());
- match *data.terminator() {
- mir::Terminator::Resume => {
+ match data.terminator().kind {
+ mir::TerminatorKind::Resume => {
if let Some(cleanup_pad) = cleanup_pad {
bcx.cleanup_ret(cleanup_pad, None);
} else {
}
}
- mir::Terminator::Goto { target } => {
+ mir::TerminatorKind::Goto { target } => {
funclet_br(bcx, self.llblock(target));
}
- mir::Terminator::If { ref cond, targets: (true_bb, false_bb) } => {
+ mir::TerminatorKind::If { ref cond, targets: (true_bb, false_bb) } => {
let cond = self.trans_operand(&bcx, cond);
let lltrue = self.llblock(true_bb);
let llfalse = self.llblock(false_bb);
bcx.cond_br(cond.immediate(), lltrue, llfalse);
}
- mir::Terminator::Switch { ref discr, ref adt_def, ref targets } => {
+ mir::TerminatorKind::Switch { ref discr, ref adt_def, ref targets } => {
let discr_lvalue = self.trans_lvalue(&bcx, discr);
let ty = discr_lvalue.ty.to_ty(bcx.tcx());
let repr = adt::represent_type(bcx.ccx(), ty);
}
}
- mir::Terminator::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
+ mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
let (otherwise, targets) = targets.split_last().unwrap();
let discr = bcx.load(self.trans_lvalue(&bcx, discr).llval);
let discr = bcx.with_block(|bcx| base::to_immediate(bcx, discr, switch_ty));
}
}
- mir::Terminator::Return => {
+ mir::TerminatorKind::Return => {
bcx.with_block(|bcx| {
self.fcx.build_return_block(bcx, DebugLoc::None);
})
}
- mir::Terminator::Drop { ref value, target, unwind } => {
+ mir::TerminatorKind::Drop { ref value, target, unwind } => {
let lvalue = self.trans_lvalue(&bcx, value);
let ty = lvalue.ty.to_ty(bcx.tcx());
// Double check for necessity to drop
}
}
- mir::Terminator::Call { ref func, ref args, ref destination, ref cleanup } => {
+ mir::TerminatorKind::Call { ref func, ref args, ref destination, ref cleanup } => {
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
let callee = self.trans_operand(&bcx, func);
self.blocks[bb.index()].llbb
}
}
+