Use PtrMetadata
instead of Len
in slice drop shims
This commit is contained in:
parent
e1a727e466
commit
8acccdc355
3 changed files with 92 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
||||||
use std::{fmt, iter};
|
use std::{fmt, iter, mem};
|
||||||
|
|
||||||
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
|
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
|
@ -6,6 +6,7 @@ use rustc_index::Idx;
|
||||||
use rustc_middle::mir::patch::MirPatch;
|
use rustc_middle::mir::patch::MirPatch;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::util::IntTypeExt;
|
use rustc_middle::ty::util::IntTypeExt;
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
@ -738,8 +739,13 @@ where
|
||||||
loop_block
|
loop_block
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
|
fn open_drop_for_array(
|
||||||
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
|
&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();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
if let Some(size) = opt_size {
|
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
|
/// Creates a pair of drop-loops of `place`, which drops its contents, even
|
||||||
/// in the case of 1 panic.
|
/// in the case of 1 panic.
|
||||||
fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
fn drop_loop_pair_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
||||||
debug!("drop_loop_pair({:?})", ety);
|
debug!("drop_loop_pair_for_slice({:?})", ety);
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let len = self.new_temp(tcx.types.usize);
|
let len = self.new_temp(tcx.types.usize);
|
||||||
let cur = 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 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 zero = self.constant_usize(0);
|
||||||
let block = BasicBlockData {
|
let block = BasicBlockData {
|
||||||
statements: vec![
|
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)),
|
self.assign(cur.into(), Rvalue::Use(zero)),
|
||||||
],
|
],
|
||||||
is_cleanup: unwind.is_cleanup(),
|
is_cleanup: unwind.is_cleanup(),
|
||||||
|
@ -863,9 +920,9 @@ where
|
||||||
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
|
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
|
||||||
ty::Array(ety, size) => {
|
ty::Array(ety, size) => {
|
||||||
let size = size.try_to_target_usize(self.tcx());
|
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),
|
_ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
|
fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
|
||||||
let mut _0: ();
|
let mut _0: ();
|
||||||
let mut _2: usize;
|
let mut _2: *mut [std::string::String; 42];
|
||||||
let mut _3: usize;
|
let mut _3: *mut [std::string::String];
|
||||||
let mut _4: *mut std::string::String;
|
let mut _4: usize;
|
||||||
let mut _5: bool;
|
let mut _5: usize;
|
||||||
let mut _6: *mut std::string::String;
|
let mut _6: *mut std::string::String;
|
||||||
let mut _7: bool;
|
let mut _7: bool;
|
||||||
|
let mut _8: *mut std::string::String;
|
||||||
|
let mut _9: bool;
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
goto -> bb8;
|
goto -> bb9;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
@ -22,34 +24,40 @@ fn std::ptr::drop_in_place(_1: *mut [String; 42]) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3 (cleanup): {
|
bb3 (cleanup): {
|
||||||
_4 = &raw mut (*_1)[_3];
|
_6 = &raw mut (*_3)[_5];
|
||||||
_3 = Add(move _3, const 1_usize);
|
_5 = Add(move _5, const 1_usize);
|
||||||
drop((*_4)) -> [return: bb4, unwind terminate(cleanup)];
|
drop((*_6)) -> [return: bb4, unwind terminate(cleanup)];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4 (cleanup): {
|
bb4 (cleanup): {
|
||||||
_5 = Eq(copy _3, copy _2);
|
_7 = Eq(copy _5, copy _4);
|
||||||
switchInt(move _5) -> [0: bb3, otherwise: bb2];
|
switchInt(move _7) -> [0: bb3, otherwise: bb2];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
_6 = &raw mut (*_1)[_3];
|
_8 = &raw mut (*_3)[_5];
|
||||||
_3 = Add(move _3, const 1_usize);
|
_5 = Add(move _5, const 1_usize);
|
||||||
drop((*_6)) -> [return: bb6, unwind: bb4];
|
drop((*_8)) -> [return: bb6, unwind: bb4];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
_7 = Eq(copy _3, copy _2);
|
_9 = Eq(copy _5, copy _4);
|
||||||
switchInt(move _7) -> [0: bb5, otherwise: bb1];
|
switchInt(move _9) -> [0: bb5, otherwise: bb1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
_2 = Len((*_1));
|
_4 = PtrMetadata(copy _3);
|
||||||
_3 = const 0_usize;
|
_5 = const 0_usize;
|
||||||
goto -> bb6;
|
goto -> bb6;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb8: {
|
bb8: {
|
||||||
goto -> bb7;
|
goto -> bb7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bb9: {
|
||||||
|
_2 = &raw mut (*_1);
|
||||||
|
_3 = move _2 as *mut [std::string::String] (PointerCoercion(Unsize, Implicit));
|
||||||
|
goto -> bb8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
_2 = Len((*_1));
|
_2 = PtrMetadata(copy _1);
|
||||||
_3 = const 0_usize;
|
_3 = const 0_usize;
|
||||||
goto -> bb6;
|
goto -> bb6;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue