Skip to content

Commit b22856d

Browse files
committed
Auto merge of #134326 - scottmcm:slice-drop-shim-ptrmetadata, r=saethlin
Use `PtrMetadata` instead of `Len` in slice drop shims I tried to do a bigger change in #134297 which didn't work, so here's the part I really wanted: Removing another use of `Len`, in favour of `PtrMetadata`. Split into two commits where the first just adds a test, so you can look at the second commit to see how the drop shim for an array changes with this PR. Reusing the same reviewer from the last one: r? BoxyUwU
2 parents bace306 + 8acccdc commit b22856d

4 files changed

+132
-10
lines changed

Diff for: compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+66-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use std::{fmt, iter};
1+
use std::{fmt, iter, mem};
22

33
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
44
use rustc_hir::lang_items::LangItem;
55
use rustc_index::Idx;
66
use rustc_middle::mir::patch::MirPatch;
77
use rustc_middle::mir::*;
88
use rustc_middle::span_bug;
9+
use rustc_middle::ty::adjustment::PointerCoercion;
910
use rustc_middle::ty::util::IntTypeExt;
1011
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
1112
use rustc_span::DUMMY_SP;
@@ -738,8 +739,13 @@ where
738739
loop_block
739740
}
740741

741-
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
742-
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
742+
fn open_drop_for_array(
743+
&mut self,
744+
array_ty: Ty<'tcx>,
745+
ety: Ty<'tcx>,
746+
opt_size: Option<u64>,
747+
) -> BasicBlock {
748+
debug!("open_drop_for_array({:?}, {:?}, {:?})", array_ty, ety, opt_size);
743749
let tcx = self.tcx();
744750

745751
if let Some(size) = opt_size {
@@ -801,13 +807,50 @@ where
801807
}
802808
}
803809

804-
self.drop_loop_pair(ety)
810+
let array_ptr_ty = Ty::new_mut_ptr(tcx, array_ty);
811+
let array_ptr = self.new_temp(array_ptr_ty);
812+
813+
let slice_ty = Ty::new_slice(tcx, ety);
814+
let slice_ptr_ty = Ty::new_mut_ptr(tcx, slice_ty);
815+
let slice_ptr = self.new_temp(slice_ptr_ty);
816+
817+
let mut delegate_block = BasicBlockData {
818+
statements: vec![
819+
self.assign(Place::from(array_ptr), Rvalue::RawPtr(Mutability::Mut, self.place)),
820+
self.assign(
821+
Place::from(slice_ptr),
822+
Rvalue::Cast(
823+
CastKind::PointerCoercion(
824+
PointerCoercion::Unsize,
825+
CoercionSource::Implicit,
826+
),
827+
Operand::Move(Place::from(array_ptr)),
828+
slice_ptr_ty,
829+
),
830+
),
831+
],
832+
is_cleanup: self.unwind.is_cleanup(),
833+
terminator: None,
834+
};
835+
836+
let array_place = mem::replace(
837+
&mut self.place,
838+
Place::from(slice_ptr).project_deeper(&[PlaceElem::Deref], tcx),
839+
);
840+
let slice_block = self.drop_loop_pair_for_slice(ety);
841+
self.place = array_place;
842+
843+
delegate_block.terminator = Some(Terminator {
844+
source_info: self.source_info,
845+
kind: TerminatorKind::Goto { target: slice_block },
846+
});
847+
self.elaborator.patch().new_block(delegate_block)
805848
}
806849

807850
/// Creates a pair of drop-loops of `place`, which drops its contents, even
808851
/// in the case of 1 panic.
809-
fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
810-
debug!("drop_loop_pair({:?})", ety);
852+
fn drop_loop_pair_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
853+
debug!("drop_loop_pair_for_slice({:?})", ety);
811854
let tcx = self.tcx();
812855
let len = self.new_temp(tcx.types.usize);
813856
let cur = self.new_temp(tcx.types.usize);
@@ -817,10 +860,24 @@ where
817860

818861
let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind);
819862

863+
let [PlaceElem::Deref] = self.place.projection.as_slice() else {
864+
span_bug!(
865+
self.source_info.span,
866+
"Expected place for slice drop shim to be *_n, but it's {:?}",
867+
self.place,
868+
);
869+
};
870+
820871
let zero = self.constant_usize(0);
821872
let block = BasicBlockData {
822873
statements: vec![
823-
self.assign(len.into(), Rvalue::Len(self.place)),
874+
self.assign(
875+
len.into(),
876+
Rvalue::UnaryOp(
877+
UnOp::PtrMetadata,
878+
Operand::Copy(Place::from(self.place.local)),
879+
),
880+
),
824881
self.assign(cur.into(), Rvalue::Use(zero)),
825882
],
826883
is_cleanup: unwind.is_cleanup(),
@@ -863,9 +920,9 @@ where
863920
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
864921
ty::Array(ety, size) => {
865922
let size = size.try_to_target_usize(self.tcx());
866-
self.open_drop_for_array(*ety, size)
923+
self.open_drop_for_array(ty, *ety, size)
867924
}
868-
ty::Slice(ety) => self.drop_loop_pair(*ety),
925+
ty::Slice(ety) => self.drop_loop_pair_for_slice(*ety),
869926

870927
_ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
871928
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// MIR for `std::ptr::drop_in_place` before AddMovesForPackedDrops
2+
3+
fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
4+
let mut _0: ();
5+
let mut _2: *mut [std::string::String; 42];
6+
let mut _3: *mut [std::string::String];
7+
let mut _4: usize;
8+
let mut _5: usize;
9+
let mut _6: *mut std::string::String;
10+
let mut _7: bool;
11+
let mut _8: *mut std::string::String;
12+
let mut _9: bool;
13+
14+
bb0: {
15+
goto -> bb9;
16+
}
17+
18+
bb1: {
19+
return;
20+
}
21+
22+
bb2 (cleanup): {
23+
resume;
24+
}
25+
26+
bb3 (cleanup): {
27+
_6 = &raw mut (*_3)[_5];
28+
_5 = Add(move _5, const 1_usize);
29+
drop((*_6)) -> [return: bb4, unwind terminate(cleanup)];
30+
}
31+
32+
bb4 (cleanup): {
33+
_7 = Eq(copy _5, copy _4);
34+
switchInt(move _7) -> [0: bb3, otherwise: bb2];
35+
}
36+
37+
bb5: {
38+
_8 = &raw mut (*_3)[_5];
39+
_5 = Add(move _5, const 1_usize);
40+
drop((*_8)) -> [return: bb6, unwind: bb4];
41+
}
42+
43+
bb6: {
44+
_9 = Eq(copy _5, copy _4);
45+
switchInt(move _9) -> [0: bb5, otherwise: bb1];
46+
}
47+
48+
bb7: {
49+
_4 = PtrMetadata(copy _3);
50+
_5 = const 0_usize;
51+
goto -> bb6;
52+
}
53+
54+
bb8: {
55+
goto -> bb7;
56+
}
57+
58+
bb9: {
59+
_2 = &raw mut (*_1);
60+
_3 = move _2 as *mut [std::string::String] (PointerCoercion(Unsize, Implicit));
61+
goto -> bb8;
62+
}
63+
}

Diff for: tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
4444
}
4545

4646
bb7: {
47-
_2 = Len((*_1));
47+
_2 = PtrMetadata(copy _1);
4848
_3 = const 0_usize;
4949
goto -> bb6;
5050
}

Diff for: tests/mir-opt/slice_drop_shim.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// if we use -Clink-dead-code.
66

77
// EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
8+
// EMIT_MIR core.ptr-drop_in_place.[String;42].AddMovesForPackedDrops.before.mir
89
fn main() {
910
let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
11+
let _fn = std::ptr::drop_in_place::<[String; 42]> as unsafe fn(_);
1012
}

0 commit comments

Comments
 (0)