about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2024-12-14 21:20:15 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2024-12-14 21:29:45 -0800
commit8acccdc355b25a9c99c38a7685ad4013562d2ec8 (patch)
treee0a5539c31077b3723466bfe05011c9528ab0d17
parente1a727e4661c4d0c85a43fa680b2f7571396807e (diff)
downloadrust-8acccdc355b25a9c99c38a7685ad4013562d2ec8.tar.gz
rust-8acccdc355b25a9c99c38a7685ad4013562d2ec8.zip
Use `PtrMetadata` instead of `Len` in slice drop shims
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs75
-rw-r--r--tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir42
-rw-r--r--tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir2
3 files changed, 92 insertions, 27 deletions
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 494b7d54d8a..f8a84674947 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -1,4 +1,4 @@
-use std::{fmt, iter};
+use std::{fmt, iter, mem};
 
 use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
 use rustc_hir::lang_items::LangItem;
@@ -6,6 +6,7 @@ use rustc_index::Idx;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
@@ -738,8 +739,13 @@ where
         loop_block
     }
 
-    fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
-        debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
+    fn open_drop_for_array(
+        &mut self,
+        array_ty: Ty<'tcx>,
+        ety: Ty<'tcx>,
+        opt_size: Option<u64>,
+    ) -> BasicBlock {
+        debug!("open_drop_for_array({:?}, {:?}, {:?})", array_ty, ety, opt_size);
         let tcx = self.tcx();
 
         if let Some(size) = opt_size {
@@ -801,13 +807,50 @@ where
             }
         }
 
-        self.drop_loop_pair(ety)
+        let array_ptr_ty = Ty::new_mut_ptr(tcx, array_ty);
+        let array_ptr = self.new_temp(array_ptr_ty);
+
+        let slice_ty = Ty::new_slice(tcx, ety);
+        let slice_ptr_ty = Ty::new_mut_ptr(tcx, slice_ty);
+        let slice_ptr = self.new_temp(slice_ptr_ty);
+
+        let mut delegate_block = BasicBlockData {
+            statements: vec![
+                self.assign(Place::from(array_ptr), Rvalue::RawPtr(Mutability::Mut, self.place)),
+                self.assign(
+                    Place::from(slice_ptr),
+                    Rvalue::Cast(
+                        CastKind::PointerCoercion(
+                            PointerCoercion::Unsize,
+                            CoercionSource::Implicit,
+                        ),
+                        Operand::Move(Place::from(array_ptr)),
+                        slice_ptr_ty,
+                    ),
+                ),
+            ],
+            is_cleanup: self.unwind.is_cleanup(),
+            terminator: None,
+        };
+
+        let array_place = mem::replace(
+            &mut self.place,
+            Place::from(slice_ptr).project_deeper(&[PlaceElem::Deref], tcx),
+        );
+        let slice_block = self.drop_loop_pair_for_slice(ety);
+        self.place = array_place;
+
+        delegate_block.terminator = Some(Terminator {
+            source_info: self.source_info,
+            kind: TerminatorKind::Goto { target: slice_block },
+        });
+        self.elaborator.patch().new_block(delegate_block)
     }
 
     /// Creates a pair of drop-loops of `place`, which drops its contents, even
     /// in the case of 1 panic.
-    fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
-        debug!("drop_loop_pair({:?})", ety);
+    fn drop_loop_pair_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
+        debug!("drop_loop_pair_for_slice({:?})", ety);
         let tcx = self.tcx();
         let len = self.new_temp(tcx.types.usize);
         let cur = self.new_temp(tcx.types.usize);
@@ -817,10 +860,24 @@ where
 
         let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind);
 
+        let [PlaceElem::Deref] = self.place.projection.as_slice() else {
+            span_bug!(
+                self.source_info.span,
+                "Expected place for slice drop shim to be *_n, but it's {:?}",
+                self.place,
+            );
+        };
+
         let zero = self.constant_usize(0);
         let block = BasicBlockData {
             statements: vec![
-                self.assign(len.into(), Rvalue::Len(self.place)),
+                self.assign(
+                    len.into(),
+                    Rvalue::UnaryOp(
+                        UnOp::PtrMetadata,
+                        Operand::Copy(Place::from(self.place.local)),
+                    ),
+                ),
                 self.assign(cur.into(), Rvalue::Use(zero)),
             ],
             is_cleanup: unwind.is_cleanup(),
@@ -863,9 +920,9 @@ where
             ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
             ty::Array(ety, size) => {
                 let size = size.try_to_target_usize(self.tcx());
-                self.open_drop_for_array(*ety, size)
+                self.open_drop_for_array(ty, *ety, size)
             }
-            ty::Slice(ety) => self.drop_loop_pair(*ety),
+            ty::Slice(ety) => self.drop_loop_pair_for_slice(*ety),
 
             _ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
         }
diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
index 197a93e99d3..13df2195ab0 100644
--- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
@@ -2,15 +2,17 @@
 
 fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
     let mut _0: ();
-    let mut _2: usize;
-    let mut _3: usize;
-    let mut _4: *mut std::string::String;
-    let mut _5: bool;
+    let mut _2: *mut [std::string::String; 42];
+    let mut _3: *mut [std::string::String];
+    let mut _4: usize;
+    let mut _5: usize;
     let mut _6: *mut std::string::String;
     let mut _7: bool;
+    let mut _8: *mut std::string::String;
+    let mut _9: bool;
 
     bb0: {
-        goto -> bb8;
+        goto -> bb9;
     }
 
     bb1: {
@@ -22,34 +24,40 @@ fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
     }
 
     bb3 (cleanup): {
-        _4 = &raw mut (*_1)[_3];
-        _3 = Add(move _3, const 1_usize);
-        drop((*_4)) -> [return: bb4, unwind terminate(cleanup)];
+        _6 = &raw mut (*_3)[_5];
+        _5 = Add(move _5, const 1_usize);
+        drop((*_6)) -> [return: bb4, unwind terminate(cleanup)];
     }
 
     bb4 (cleanup): {
-        _5 = Eq(copy _3, copy _2);
-        switchInt(move _5) -> [0: bb3, otherwise: bb2];
+        _7 = Eq(copy _5, copy _4);
+        switchInt(move _7) -> [0: bb3, otherwise: bb2];
     }
 
     bb5: {
-        _6 = &raw mut (*_1)[_3];
-        _3 = Add(move _3, const 1_usize);
-        drop((*_6)) -> [return: bb6, unwind: bb4];
+        _8 = &raw mut (*_3)[_5];
+        _5 = Add(move _5, const 1_usize);
+        drop((*_8)) -> [return: bb6, unwind: bb4];
     }
 
     bb6: {
-        _7 = Eq(copy _3, copy _2);
-        switchInt(move _7) -> [0: bb5, otherwise: bb1];
+        _9 = Eq(copy _5, copy _4);
+        switchInt(move _9) -> [0: bb5, otherwise: bb1];
     }
 
     bb7: {
-        _2 = Len((*_1));
-        _3 = const 0_usize;
+        _4 = PtrMetadata(copy _3);
+        _5 = const 0_usize;
         goto -> bb6;
     }
 
     bb8: {
         goto -> bb7;
     }
+
+    bb9: {
+        _2 = &raw mut (*_1);
+        _3 = move _2 as *mut [std::string::String] (PointerCoercion(Unsize, Implicit));
+        goto -> bb8;
+    }
 }
diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
index 4d1eaa6ffe3..0633b765644 100644
--- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
@@ -44,7 +44,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
     }
 
     bb7: {
-        _2 = Len((*_1));
+        _2 = PtrMetadata(copy _1);
         _3 = const 0_usize;
         goto -> bb6;
     }