diff options
| author | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2022-08-01 13:51:58 -0700 |
|---|---|---|
| committer | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2023-06-16 13:41:06 -0700 |
| commit | a5c6cb888eac7ad8905a3902b985e412aaceb002 (patch) | |
| tree | 18124f347f8405e4d746023018fa354580efac00 /compiler/rustc_mir_dataflow/src | |
| parent | 0966f3202d1e811cd3aa35ac876b61a211b4819a (diff) | |
| download | rust-a5c6cb888eac7ad8905a3902b985e412aaceb002.tar.gz rust-a5c6cb888eac7ad8905a3902b985e412aaceb002.zip | |
remove box_free and replace with drop impl
Diffstat (limited to 'compiler/rustc_mir_dataflow/src')
| -rw-r--r-- | compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 100 |
1 files changed, 26 insertions, 74 deletions
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index d615c83d621..4fc45eaf522 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -409,8 +409,15 @@ where self.drop_ladder(fields, succ, unwind).0 } + /// Drops the T contained in a `Box<T>` if it has not been moved out of #[instrument(level = "debug", ret)] - fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock { + fn open_drop_for_box_contents( + &mut self, + adt: ty::AdtDef<'tcx>, + substs: SubstsRef<'tcx>, + succ: BasicBlock, + unwind: Unwind, + ) -> BasicBlock { // drop glue is sent straight to codegen // box cannot be directly dereferenced let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), substs); @@ -425,11 +432,7 @@ where let interior_path = self.elaborator.deref_subpath(self.path); - let succ = self.box_free_block(adt, substs, self.succ, self.unwind); - let unwind_succ = - self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup)); - - self.drop_subpath(interior, interior_path, succ, unwind_succ) + self.drop_subpath(interior, interior_path, succ, unwind) } #[instrument(level = "debug", ret)] @@ -453,7 +456,15 @@ where self.open_drop_for_adt_contents(adt, substs) }; - if adt.has_dtor(self.tcx()) { + if adt.is_box() { + // we need to drop the inside of the box before running the destructor + let succ = self.destructor_call_block(contents_drop); + let unwind = contents_drop + .1 + .map(|unwind| self.destructor_call_block((unwind, Unwind::InCleanup))); + + self.open_drop_for_box_contents(adt, substs, succ, unwind) + } else if adt.has_dtor(self.tcx()) { self.destructor_call_block(contents_drop) } else { contents_drop.0 @@ -650,7 +661,13 @@ where }), is_cleanup: unwind.is_cleanup(), }; - self.elaborator.patch().new_block(result) + + let destructor_block = self.elaborator.patch().new_block(result); + + let block_start = Location { block: destructor_block, statement_index: 0 }; + self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow); + + self.drop_flag_test_block(destructor_block, succ, unwind) } /// Create a loop that drops an array: @@ -851,13 +868,7 @@ where self.open_drop_for_tuple(&tys) } ty::Tuple(fields) => self.open_drop_for_tuple(fields), - ty::Adt(def, substs) => { - if def.is_box() { - self.open_drop_for_box(*def, substs) - } else { - self.open_drop_for_adt(*def, substs) - } - } + ty::Adt(def, substs) => self.open_drop_for_adt(*def, substs), ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind), ty::Array(ety, size) => { let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env()); @@ -905,65 +916,6 @@ where blk } - /// Creates a block that frees the backing memory of a `Box` if its drop is required (either - /// statically or by checking its drop flag). - /// - /// The contained value will not be dropped. - fn box_free_block( - &mut self, - adt: ty::AdtDef<'tcx>, - substs: SubstsRef<'tcx>, - target: BasicBlock, - unwind: Unwind, - ) -> BasicBlock { - let block = self.unelaborated_free_block(adt, substs, target, unwind); - self.drop_flag_test_block(block, target, unwind) - } - - /// Creates a block that frees the backing memory of a `Box` (without dropping the contained - /// value). - fn unelaborated_free_block( - &mut self, - adt: ty::AdtDef<'tcx>, - substs: SubstsRef<'tcx>, - target: BasicBlock, - unwind: Unwind, - ) -> BasicBlock { - let tcx = self.tcx(); - let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); - let free_func = tcx.require_lang_item(LangItem::BoxFree, Some(self.source_info.span)); - let args = adt - .variant(FIRST_VARIANT) - .fields - .iter() - .enumerate() - .map(|(i, f)| { - let field = FieldIdx::new(i); - let field_ty = f.ty(tcx, substs); - Operand::Move(tcx.mk_place_field(self.place, field, field_ty)) - }) - .collect(); - - let call = TerminatorKind::Call { - func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), - args, - destination: unit_temp, - target: Some(target), - unwind: if unwind.is_cleanup() { - UnwindAction::Terminate - } else { - UnwindAction::Continue - }, - from_hir_call: false, - fn_span: self.source_info.span, - }; // FIXME(#43234) - let free_block = self.new_block(unwind, call); - - let block_start = Location { block: free_block, statement_index: 0 }; - self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow); - free_block - } - fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = TerminatorKind::Drop { place: self.place, |
