]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir/src/util/elaborate_drops.rs
Refactor how SwitchInt stores jump targets
[rust.git] / compiler / rustc_mir / src / util / elaborate_drops.rs
index bf0a6be9a7d8e54ad0e87a770cd9d4f83036b8fb..4a48b335ce9640fbc414b3298f9dccd31f113f73 100644 (file)
@@ -231,8 +231,6 @@ pub fn elaborate_drop(&mut self, bb: BasicBlock) {
                     .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 {
@@ -243,9 +241,7 @@ pub fn elaborate_drop(&mut self, bb: BasicBlock) {
                 );
             }
             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 });
@@ -317,7 +313,7 @@ fn drop_subpath(
                 // our own drop flag.
                 path: self.path,
             }
-            .complete_drop(None, succ, unwind)
+            .complete_drop(succ, unwind)
         }
     }
 
@@ -346,13 +342,7 @@ fn drop_ladder_bottom(&mut self) -> (BasicBlock, 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
@@ -598,8 +588,10 @@ fn adt_switch_block(
                 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(),
@@ -768,7 +760,7 @@ fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> Basic
         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![
@@ -781,11 +773,11 @@ fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> Basic
                 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),
-                    ],
+                    ),
                 },
             }),
         };
@@ -884,11 +876,7 @@ fn open_drop(&mut self) -> BasicBlock {
                     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)
@@ -899,20 +887,10 @@ fn open_drop(&mut self) -> BasicBlock {
         }
     }
 
-    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)
     }
@@ -927,6 +905,11 @@ fn drop_flag_reset_block(
     ) -> 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);
@@ -1044,11 +1027,6 @@ fn new_temp(&mut self, ty: Ty<'tcx>) -> Local {
         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,