diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a35803522611..fa7ba3e6a62a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -453,12 +453,6 @@ pub enum TerminatorKind<'tcx> { target: BasicBlock, }, - /// jump to branch 0 if this lvalue evaluates to true - If { - cond: Operand<'tcx>, - targets: (BasicBlock, BasicBlock), - }, - /// lvalue evaluates to some enum; jump depending on the branch Switch { discr: Lvalue<'tcx>, @@ -470,7 +464,7 @@ pub enum TerminatorKind<'tcx> { /// to one of the targets, and otherwise fallback to `otherwise` SwitchInt { /// discriminant value being tested - discr: Lvalue<'tcx>, + discr: Operand<'tcx>, /// type of value being tested switch_ty: Ty<'tcx>, @@ -550,7 +544,6 @@ impl<'tcx> TerminatorKind<'tcx> { use self::TerminatorKind::*; match *self { Goto { target: ref b } => slice::ref_slice(b).into_cow(), - If { targets: (b1, b2), .. } => vec![b1, b2].into_cow(), Switch { targets: ref b, .. } => b[..].into_cow(), SwitchInt { targets: ref b, .. } => b[..].into_cow(), Resume => (&[]).into_cow(), @@ -580,7 +573,6 @@ impl<'tcx> TerminatorKind<'tcx> { use self::TerminatorKind::*; match *self { Goto { target: ref mut b } => vec![b], - If { targets: (ref mut b1, ref mut b2), .. } => vec![b1, b2], Switch { targets: ref mut b, .. } => b.iter_mut().collect(), SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(), Resume => Vec::new(), @@ -659,7 +651,6 @@ impl<'tcx> TerminatorKind<'tcx> { use self::TerminatorKind::*; match *self { Goto { .. } => write!(fmt, "goto"), - If { cond: ref lv, .. } => write!(fmt, "if({:?})", lv), Switch { discr: ref lv, .. } => write!(fmt, "switch({:?})", lv), SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv), Return => write!(fmt, "return"), @@ -710,7 +701,6 @@ impl<'tcx> TerminatorKind<'tcx> { match *self { Return | Resume | Unreachable => vec![], Goto { .. } => vec!["".into()], - If { .. } => vec!["true".into(), "false".into()], Switch { ref adt_def, .. } => { adt_def.variants .iter() diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 921b4e78b32c..1e27a02287fd 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -14,7 +14,6 @@ use ty::subst::Substs; use ty::{ClosureSubsts, Region, Ty}; use mir::*; use rustc_const_math::ConstUsize; -use rustc_data_structures::tuple_slice::TupleSlice; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; @@ -363,14 +362,6 @@ macro_rules! make_mir_visitor { self.visit_branch(block, target); } - TerminatorKind::If { ref $($mutability)* cond, - ref $($mutability)* targets } => { - self.visit_operand(cond, source_location); - for &target in targets.as_slice() { - self.visit_branch(block, target); - } - } - TerminatorKind::Switch { ref $($mutability)* discr, adt_def: _, ref targets } => { @@ -384,7 +375,7 @@ macro_rules! make_mir_visitor { ref $($mutability)* switch_ty, ref $($mutability)* values, ref targets } => { - self.visit_lvalue(discr, LvalueContext::Inspect, source_location); + self.visit_operand(discr, source_location); self.visit_ty(switch_ty); for value in values { self.visit_const_val(value, source_location); diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs index f11cf90834dd..8dd591fa2e77 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs @@ -454,10 +454,6 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> self.propagate_bits_into_entry_set_for(in_out, changed, target); self.propagate_bits_into_entry_set_for(in_out, changed, unwind); } - mir::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); - } mir::TerminatorKind::Switch { ref targets, .. } | mir::TerminatorKind::SwitchInt { ref targets, .. } => { for target in targets { diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index d2f744bde2d6..45f534767e4e 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -813,9 +813,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { (true, false) => on_set, (true, true) => { let flag = self.drop_flag(c.path).unwrap(); - self.new_block(c, is_cleanup, TerminatorKind::If { - cond: Operand::Consume(flag), - targets: (on_set, on_unset) + let boolty = self.tcx.types.bool; + self.new_block(c, is_cleanup, TerminatorKind::SwitchInt { + discr: Operand::Consume(flag), + switch_ty: boolty, + values: vec![ConstVal::Bool(true)], + targets: vec![on_set, on_unset], }) } } diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 806395c857a8..9e7e5ec9ee86 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -464,7 +464,6 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { self.gather_move(loc, &Lvalue::Local(RETURN_POINTER)); } - TerminatorKind::If { .. } | TerminatorKind::Assert { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Switch { .. } => { diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 3d4af259ec9f..2b4336ba66f0 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -15,6 +15,7 @@ use build::expr::category::{Category, RvalueFunc}; use hair::*; use rustc::ty; use rustc::mir::*; +use rustc::middle::const_val::ConstVal; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Compile `expr`, storing the result into `destination`, which @@ -69,9 +70,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let mut then_block = this.cfg.start_new_block(); let mut else_block = this.cfg.start_new_block(); - this.cfg.terminate(block, source_info, TerminatorKind::If { - cond: operand, - targets: (then_block, else_block) + this.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { + discr: operand, + switch_ty: this.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![then_block, else_block], }); unpack!(then_block = this.into(destination, then_block, then_expr)); @@ -111,16 +114,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let lhs = unpack!(block = this.as_operand(block, lhs)); let blocks = match op { - LogicalOp::And => (else_block, false_block), - LogicalOp::Or => (true_block, else_block), + LogicalOp::And => vec![else_block, false_block], + LogicalOp::Or => vec![true_block, else_block], }; - this.cfg.terminate(block, source_info, - TerminatorKind::If { cond: lhs, targets: blocks }); + this.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { + discr: lhs, + switch_ty: this.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: blocks, + }); let rhs = unpack!(else_block = this.as_operand(else_block, rhs)); - this.cfg.terminate(else_block, source_info, TerminatorKind::If { - cond: rhs, - targets: (true_block, false_block) + this.cfg.terminate(else_block, source_info, TerminatorKind::SwitchInt { + discr: rhs, + switch_ty: this.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![true_block, false_block], }); this.cfg.push_assign_constant( @@ -180,9 +189,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { loop_block_end = this.as_operand(loop_block, cond_expr)); body_block = this.cfg.start_new_block(); this.cfg.terminate(loop_block_end, source_info, - TerminatorKind::If { - cond: cond, - targets: (body_block, exit_block) + TerminatorKind::SwitchInt { + discr: cond, + switch_ty: this.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![body_block, exit_block], }); // if the test is false, there's no `break` to assign `destination`, so diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 5c3d93ffda9c..0898d06d2e47 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -672,9 +672,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_info = self.source_info(guard.span); let cond = unpack!(block = self.as_operand(block, guard)); let otherwise = self.cfg.start_new_block(); - self.cfg.terminate(block, source_info, - TerminatorKind::If { cond: cond, - targets: (arm_block, otherwise)}); + self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { + discr: cond, + switch_ty: self.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![arm_block, otherwise], + }); Some(otherwise) } else { let source_info = self.source_info(candidate.span); diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index a35b2925ae27..291bd65d5777 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -221,10 +221,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { v => span_bug!(test.span, "expected boolean value but got {:?}", v) }; - (targets, - TerminatorKind::If { - cond: Operand::Consume(lvalue.clone()), - targets: (true_bb, else_bb) + (targets, TerminatorKind::SwitchInt { + discr: Operand::Consume(lvalue.clone()), + switch_ty: self.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![true_bb, else_bb] }) } @@ -240,7 +241,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (targets.clone(), TerminatorKind::SwitchInt { - discr: lvalue.clone(), + discr: Operand::Consume(lvalue.clone()), switch_ty: switch_ty, values: options.clone(), targets: targets @@ -314,9 +315,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // check the result let block = self.cfg.start_new_block(); - self.cfg.terminate(eq_block, source_info, TerminatorKind::If { - cond: Operand::Consume(eq_result), - targets: (block, fail), + self.cfg.terminate(eq_block, source_info, TerminatorKind::SwitchInt { + discr: Operand::Consume(eq_result), + switch_ty: self.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![block, fail], }); vec![block, fail] @@ -362,9 +365,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // branch based on result let target_blocks: Vec<_> = vec![self.cfg.start_new_block(), self.cfg.start_new_block()]; - self.cfg.terminate(block, source_info, TerminatorKind::If { - cond: Operand::Consume(result), - targets: (target_blocks[0], target_blocks[1]) + self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { + discr: Operand::Consume(result), + switch_ty: self.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: target_blocks.clone(), }); target_blocks @@ -389,9 +394,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // branch based on result let target_block = self.cfg.start_new_block(); - self.cfg.terminate(block, source_info, TerminatorKind::If { - cond: Operand::Consume(result), - targets: (target_block, fail_block) + self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { + discr: Operand::Consume(result), + switch_ty: self.hir.bool_ty(), + values: vec![ConstVal::Bool(true)], + targets: vec![target_block, fail_block] }); target_block diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 01dc01c5ecfd..4ac67cfb2fca 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -134,7 +134,8 @@ pub enum ExprKind<'tcx> { op: LogicalOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx>, - }, + }, // NOT overloaded! + // LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands. Unary { op: UnOp, arg: ExprRef<'tcx>, diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 6ef5720b330c..425df65659c6 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -28,7 +28,6 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads { TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::Unreachable | - TerminatorKind::If { .. } | TerminatorKind::Switch { .. } | TerminatorKind::SwitchInt { .. } => { /* nothing to do */ diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 16371be576b0..bda4c94625f8 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -394,7 +394,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return Qualif::empty(); } - TerminatorKind::If {..} | TerminatorKind::Switch {..} | TerminatorKind::SwitchInt {..} | TerminatorKind::DropAndReplace { .. } | diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index d5fc90289e2c..1127f50fe508 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -209,7 +209,6 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { // turn a branch with all successors identical to a goto fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool { match terminator.kind { - TerminatorKind::If { .. } | TerminatorKind::Switch { .. } | TerminatorKind::SwitchInt { .. } => {}, _ => return false diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 8759a340d7e3..424250586b16 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -30,17 +30,17 @@ impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> { for block in mir.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { - TerminatorKind::If { ref targets, cond: Operand::Constant(Constant { - literal: Literal::Value { - value: ConstVal::Bool(cond) - }, .. - }) } => { - if cond { - TerminatorKind::Goto { target: targets.0 } - } else { - TerminatorKind::Goto { target: targets.1 } - } - } + // TerminatorKind::If { ref targets, cond: Operand::Constant(Constant { + // literal: Literal::Value { + // value: ConstVal::Bool(cond) + // }, .. + // }) } => { + // if cond { + // TerminatorKind::Goto { target: targets.0 } + // } else { + // TerminatorKind::Goto { target: targets.1 } + // } + // } TerminatorKind::Assert { target, cond: Operand::Constant(Constant { literal: Literal::Value { diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 529fe564af02..9d2ad3143865 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -423,18 +423,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { lv_ty, rv_ty, terr); } } - - TerminatorKind::If { ref cond, .. } => { - let cond_ty = cond.ty(mir, tcx); - match cond_ty.sty { - ty::TyBool => {} - _ => { - span_mirbug!(self, term, "bad If ({:?}, not bool", cond_ty); - } - } - } TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => { - let discr_ty = discr.ty(mir, tcx).to_ty(tcx); + let discr_ty = discr.ty(mir, tcx); if let Err(terr) = self.sub_types(discr_ty, switch_ty) { span_mirbug!(self, term, "bad SwitchInt ({:?} on {:?}): {:?}", switch_ty, discr_ty, terr); @@ -603,10 +593,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { match block.terminator().kind { TerminatorKind::Goto { target } => self.assert_iscleanup(mir, block, target, is_cleanup), - TerminatorKind::If { targets: (on_true, on_false), .. } => { - self.assert_iscleanup(mir, block, on_true, is_cleanup); - self.assert_iscleanup(mir, block, on_false, is_cleanup); - } TerminatorKind::Switch { ref targets, .. } | TerminatorKind::SwitchInt { ref targets, .. } => { for target in targets { diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index e29febdb712d..fef61128d04e 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -148,7 +148,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { self.record("TerminatorKind", kind); self.record(match *kind { TerminatorKind::Goto { .. } => "TerminatorKind::Goto", - TerminatorKind::If { .. } => "TerminatorKind::If", TerminatorKind::Switch { .. } => "TerminatorKind::Switch", TerminatorKind::SwitchInt { .. } => "TerminatorKind::SwitchInt", TerminatorKind::Resume => "TerminatorKind::Resume", diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 2a1ab10d74e1..97118a720629 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -204,7 +204,6 @@ pub fn cleanup_kinds<'a, 'tcx>(mir: &mir::Mir<'tcx>) -> IndexVec { /* nothing to do */ diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index f04f7ab9ed1a..b22c16a2955b 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -136,14 +136,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { funclet_br(self, bcx, target); } - mir::TerminatorKind::If { ref cond, targets: (true_bb, false_bb) } => { - let cond = self.trans_operand(&bcx, cond); - - let lltrue = llblock(self, true_bb); - let llfalse = llblock(self, false_bb); - bcx.cond_br(cond.immediate(), lltrue, llfalse); - } - 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()); @@ -180,10 +172,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { + // TODO: cond_br if only 1 value let (otherwise, targets) = targets.split_last().unwrap(); - let lv = self.trans_lvalue(&bcx, discr); - let discr = bcx.load(lv.llval, lv.alignment.to_align()); - let discr = base::to_immediate(&bcx, discr, switch_ty); + let discr = self.trans_operand(&bcx, discr).immediate(); let switch = bcx.switch(discr, llblock(self, *otherwise), values.len()); for (value, target) in values.iter().zip(targets) { let val = Const::from_constval(bcx.ccx, value.clone(), switch_ty); diff --git a/src/test/ui/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs index 22d603563de1..2231c3c24228 100644 --- a/src/test/ui/custom-derive/issue-36935.rs +++ b/src/test/ui/custom-derive/issue-36935.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:plugin.rs +// ignore-stage1 #![feature(proc_macro)]