don't generate drop ladder steps for fields that don't need dropping

This commit is contained in:
Ariel Ben-Yehuda 2016-06-16 00:24:31 +03:00
parent 5755936a63
commit 2960bc8246

View File

@ -548,17 +548,26 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
/// ELAB(drop location.2 [target=`c.unwind]) /// ELAB(drop location.2 [target=`c.unwind])
fn drop_ladder<'a>(&mut self, fn drop_ladder<'a>(&mut self,
c: &DropCtxt<'a, 'tcx>, c: &DropCtxt<'a, 'tcx>,
fields: &[(Lvalue<'tcx>, Option<MovePathIndex>)]) fields: Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>)
-> BasicBlock -> BasicBlock
{ {
debug!("drop_ladder({:?}, {:?})", c, fields); debug!("drop_ladder({:?}, {:?})", c, fields);
let mut fields = fields;
fields.retain(|&(ref lvalue, _)| {
let ty = self.mir.lvalue_ty(self.tcx, lvalue).to_ty(self.tcx);
self.tcx.type_needs_drop_given_env(ty, self.param_env())
});
debug!("drop_ladder - fields needing drop: {:?}", fields);
let unwind_ladder = if c.is_cleanup { let unwind_ladder = if c.is_cleanup {
None None
} else { } else {
Some(self.drop_halfladder(c, None, c.unwind.unwrap(), &fields, true)) Some(self.drop_halfladder(c, None, c.unwind.unwrap(), &fields, true))
}; };
self.drop_halfladder(c, unwind_ladder, c.succ, fields, c.is_cleanup) self.drop_halfladder(c, unwind_ladder, c.succ, &fields, c.is_cleanup)
.last().cloned().unwrap_or(c.succ) .last().cloned().unwrap_or(c.succ)
} }
@ -567,7 +576,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
{ {
debug!("open_drop_for_tuple({:?}, {:?})", c, tys); debug!("open_drop_for_tuple({:?}, {:?})", c, tys);
let fields: Vec<_> = tys.iter().enumerate().map(|(i, &ty)| { let fields = tys.iter().enumerate().map(|(i, &ty)| {
(c.lvalue.clone().field(Field::new(i), ty), (c.lvalue.clone().field(Field::new(i), ty),
super::move_path_children_matching( super::move_path_children_matching(
&self.move_data().move_paths, c.path, |proj| match proj { &self.move_data().move_paths, c.path, |proj| match proj {
@ -579,7 +588,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
)) ))
}).collect(); }).collect();
self.drop_ladder(c, &fields) self.drop_ladder(c, fields)
} }
fn open_drop_for_box<'a>(&mut self, c: &DropCtxt<'a, 'tcx>, ty: Ty<'tcx>) fn open_drop_for_box<'a>(&mut self, c: &DropCtxt<'a, 'tcx>, ty: Ty<'tcx>)
@ -634,7 +643,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
variant_path, variant_path,
&adt.variants[variant_index], &adt.variants[variant_index],
substs); substs);
self.drop_ladder(c, &fields) self.drop_ladder(c, fields)
} else { } else {
// variant not found - drop the entire enum // variant not found - drop the entire enum
if let None = *drop_block { if let None = *drop_block {
@ -659,7 +668,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
&adt.variants[0], &adt.variants[0],
substs substs
); );
self.drop_ladder(c, &fields) self.drop_ladder(c, fields)
} }
_ => { _ => {
let variant_drops : Vec<BasicBlock> = let variant_drops : Vec<BasicBlock> =