.patch_terminator(bb, TerminatorKind::Goto { target: self.succ });
}
DropStyle::Static => {
- let loc = self.terminator_loc(bb);
- self.elaborator.clear_drop_flag(loc, self.path, DropFlagMode::Deep);
self.elaborator.patch().patch_terminator(
bb,
TerminatorKind::Drop {
);
}
DropStyle::Conditional => {
- let unwind = self.unwind; // FIXME(#43234)
- let succ = self.succ;
- let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind);
+ let drop_bb = self.complete_drop(self.succ, self.unwind);
self.elaborator
.patch()
.patch_terminator(bb, TerminatorKind::Goto { target: drop_bb });
// our own drop flag.
path: self.path,
}
- .complete_drop(None, succ, unwind)
+ .complete_drop(succ, unwind)
}
}
// Clear the "master" drop flag at the end. This is needed
// because the "master" drop protects the ADT's discriminant,
// which is invalidated after the ADT is dropped.
- let (succ, unwind) = (self.succ, self.unwind); // FIXME(#43234)
- (
- self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind),
- unwind.map(|unwind| {
- self.drop_flag_reset_block(DropFlagMode::Shallow, unwind, Unwind::InCleanup)
- }),
- )
+ (self.drop_flag_reset_block(DropFlagMode::Shallow, self.succ, self.unwind), self.unwind)
}
/// Creates a full drop ladder, consisting of 2 connected half-drop-ladders
kind: TerminatorKind::SwitchInt {
discr: Operand::Move(discr),
switch_ty: discr_ty,
- values: From::from(values.to_owned()),
- targets: blocks,
+ targets: SwitchTargets::new(
+ values.iter().copied().zip(blocks.iter().copied()),
+ *blocks.last().unwrap(),
+ ),
},
}),
is_cleanup: unwind.is_cleanup(),
let elem_size = Place::from(self.new_temp(tcx.types.usize));
let len = Place::from(self.new_temp(tcx.types.usize));
- static USIZE_SWITCH_ZERO: &[u128] = &[0];
+ static USIZE_SWITCH_ZERO: &[u128; 1] = &[0];
let base_block = BasicBlockData {
statements: vec![
kind: TerminatorKind::SwitchInt {
discr: move_(elem_size),
switch_ty: tcx.types.usize,
- values: From::from(USIZE_SWITCH_ZERO),
- targets: vec![
+ targets: SwitchTargets::static_if(
+ USIZE_SWITCH_ZERO,
self.drop_loop_pair(ety, false, len),
self.drop_loop_pair(ety, true, len),
- ],
+ ),
},
}),
};
self.open_drop_for_adt(def, substs)
}
}
- ty::Dynamic(..) => {
- let unwind = self.unwind; // FIXME(#43234)
- let succ = self.succ;
- self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
- }
+ ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
ty::Array(ety, size) => {
let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env());
self.open_drop_for_array(ety, size)
}
}
- fn complete_drop(
- &mut self,
- drop_mode: Option<DropFlagMode>,
- succ: BasicBlock,
- unwind: Unwind,
- ) -> BasicBlock {
- debug!("complete_drop({:?},{:?})", self, drop_mode);
+ fn complete_drop(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock {
+ debug!("complete_drop(succ={:?}, unwind={:?})", succ, unwind);
let drop_block = self.drop_block(succ, unwind);
- let drop_block = if let Some(mode) = drop_mode {
- self.drop_flag_reset_block(mode, drop_block, unwind)
- } else {
- drop_block
- };
self.drop_flag_test_block(drop_block, succ, unwind)
}
) -> BasicBlock {
debug!("drop_flag_reset_block({:?},{:?})", self, mode);
+ if unwind.is_cleanup() {
+ // The drop flag isn't read again on the unwind path, so don't
+ // bother setting it.
+ return succ;
+ }
let block = self.new_block(unwind, TerminatorKind::Goto { target: succ });
let block_start = Location { block, statement_index: 0 };
self.elaborator.clear_drop_flag(block_start, self.path, mode);
self.elaborator.patch().new_temp(ty, self.source_info.span)
}
- fn terminator_loc(&mut self, bb: BasicBlock) -> Location {
- let body = self.elaborator.body();
- self.elaborator.patch().terminator_loc(body, bb)
- }
-
fn constant_usize(&self, val: u16) -> Operand<'tcx> {
Operand::Constant(box Constant {
span: self.source_info.span,