Don't project into NonNull
when dropping a Box
This commit is contained in:
parent
54a0f387ea
commit
7e35729bfc
8 changed files with 168 additions and 10 deletions
|
@ -89,6 +89,7 @@ pub(crate) trait DropElaborator<'a, 'tcx>: fmt::Debug {
|
|||
|
||||
// Accessors
|
||||
|
||||
fn patch_ref(&self) -> &MirPatch<'tcx>;
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx>;
|
||||
fn body(&self) -> &'a Body<'tcx>;
|
||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||
|
@ -180,7 +181,14 @@ where
|
|||
{
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> {
|
||||
place.ty(self.elaborator.body(), self.tcx()).ty
|
||||
if place.local < self.elaborator.body().local_decls.next_index() {
|
||||
place.ty(self.elaborator.body(), self.tcx()).ty
|
||||
} else {
|
||||
// We don't have a slice with all the locals, since some are in the patch.
|
||||
tcx::PlaceTy::from_ty(self.elaborator.patch_ref().local_ty(place.local))
|
||||
.multi_projection_ty(self.elaborator.tcx(), place.projection)
|
||||
.ty
|
||||
}
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
|
@ -410,12 +418,26 @@ where
|
|||
|
||||
let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::ZERO, unique_ty);
|
||||
let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::ZERO, nonnull_ty);
|
||||
let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::ZERO, ptr_ty);
|
||||
let interior = self.tcx().mk_place_deref(ptr_place);
|
||||
|
||||
let ptr_local = self.new_temp(ptr_ty);
|
||||
|
||||
let interior = self.tcx().mk_place_deref(Place::from(ptr_local));
|
||||
let interior_path = self.elaborator.deref_subpath(self.path);
|
||||
|
||||
self.drop_subpath(interior, interior_path, succ, unwind)
|
||||
let do_drop_bb = self.drop_subpath(interior, interior_path, succ, unwind);
|
||||
|
||||
let setup_bbd = BasicBlockData {
|
||||
statements: vec![self.assign(
|
||||
Place::from(ptr_local),
|
||||
Rvalue::Cast(CastKind::Transmute, Operand::Copy(nonnull_place), ptr_ty),
|
||||
)],
|
||||
terminator: Some(Terminator {
|
||||
kind: TerminatorKind::Goto { target: do_drop_bb },
|
||||
source_info: self.source_info,
|
||||
}),
|
||||
is_cleanup: unwind.is_cleanup(),
|
||||
};
|
||||
self.elaborator.patch().new_block(setup_bbd)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", ret)]
|
||||
|
|
|
@ -138,6 +138,10 @@ impl InitializationData<'_, '_> {
|
|||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for ElaborateDropsCtxt<'a, 'tcx> {
|
||||
type Path = MovePathIndex;
|
||||
|
||||
fn patch_ref(&self) -> &MirPatch<'tcx> {
|
||||
&self.patch
|
||||
}
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
||||
&mut self.patch
|
||||
}
|
||||
|
|
|
@ -166,6 +166,14 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
Local::new(index)
|
||||
}
|
||||
|
||||
/// Returns the type of a local that's newly-added in the patch.
|
||||
pub(crate) fn local_ty(&self, local: Local) -> Ty<'tcx> {
|
||||
let local = local.as_usize();
|
||||
assert!(local < self.next_local);
|
||||
let new_local_idx = self.new_locals.len() - (self.next_local - local);
|
||||
self.new_locals[new_local_idx].ty
|
||||
}
|
||||
|
||||
pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock {
|
||||
let block = BasicBlock::new(self.patch_map.len());
|
||||
debug!("MirPatch: new_block: {:?}: {:?}", block, data);
|
||||
|
|
|
@ -350,6 +350,9 @@ impl fmt::Debug for DropShimElaborator<'_, '_> {
|
|||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
|
||||
type Path = ();
|
||||
|
||||
fn patch_ref(&self) -> &MirPatch<'tcx> {
|
||||
&self.patch
|
||||
}
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
||||
&mut self.patch
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue