about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2016-06-16 00:24:31 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2016-06-16 00:48:02 +0300
commit2960bc8246d7ce477ca2edaff68e0ca8caa8d608 (patch)
treeef935e61c7b3ea99fcf2f65b838bd7bf3a30f976 /src
parent5755936a635bf0560947ee1af2ec69f644a70d19 (diff)
downloadrust-2960bc8246d7ce477ca2edaff68e0ca8caa8d608.tar.gz
rust-2960bc8246d7ce477ca2edaff68e0ca8caa8d608.zip
don't generate drop ladder steps for fields that don't need dropping
Diffstat (limited to 'src')
-rw-r--r--src/librustc_borrowck/borrowck/mir/elaborate_drops.rs21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
index 74ebad107eb..065cbbf76b3 100644
--- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
+++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
@@ -548,17 +548,26 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     ///     ELAB(drop location.2 [target=`c.unwind])
     fn drop_ladder<'a>(&mut self,
                        c: &DropCtxt<'a, 'tcx>,
-                       fields: &[(Lvalue<'tcx>, Option<MovePathIndex>)])
+                       fields: Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>)
                        -> BasicBlock
     {
         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 {
             None
         } else {
             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)
     }
 
@@ -567,7 +576,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     {
         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),
              super::move_path_children_matching(
                  &self.move_data().move_paths, c.path, |proj| match proj {
@@ -579,7 +588,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
             ))
         }).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>)
@@ -634,7 +643,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                 variant_path,
                 &adt.variants[variant_index],
                 substs);
-            self.drop_ladder(c, &fields)
+            self.drop_ladder(c, fields)
         } else {
             // variant not found - drop the entire enum
             if let None = *drop_block {
@@ -659,7 +668,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                     &adt.variants[0],
                     substs
                 );
-                self.drop_ladder(c, &fields)
+                self.drop_ladder(c, fields)
             }
             _ => {
                 let variant_drops : Vec<BasicBlock> =