Auto merge of #100036 - DrMeepster:box_free_free_box, r=oli-obk
Remove `box_free` lang item This PR removes the `box_free` lang item, replacing it with `Box`'s `Drop` impl. Box dropping is still slightly magic because the contained value is still dropped by the compiler.
This commit is contained in:
commit
a8a29070f0
17 changed files with 91 additions and 146 deletions
|
@ -546,7 +546,8 @@ impl<T> Box<T> {
|
|||
|
||||
impl<T: ?Sized, A> Drop for Box<T, A> {
|
||||
fn drop(&mut self) {
|
||||
// drop is currently performed by compiler.
|
||||
// inner value is dropped by compiler
|
||||
libc::free(self.0.pointer.0 as *mut u8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,11 +564,6 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
|||
libc::malloc(size)
|
||||
}
|
||||
|
||||
#[lang = "box_free"]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, _alloc: ()) {
|
||||
libc::free(ptr.pointer.0 as *mut u8);
|
||||
}
|
||||
|
||||
#[lang = "drop"]
|
||||
pub trait Drop {
|
||||
fn drop(&mut self);
|
||||
|
|
|
@ -490,7 +490,8 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> fo
|
|||
|
||||
impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
|
||||
fn drop(&mut self) {
|
||||
// drop is currently performed by compiler.
|
||||
// inner value is dropped by compiler
|
||||
libc::free(self.pointer.0 as *mut u8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,11 +508,6 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
|||
libc::malloc(size)
|
||||
}
|
||||
|
||||
#[lang = "box_free"]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, _alloc: ()) {
|
||||
libc::free(ptr.pointer.0 as *mut u8);
|
||||
}
|
||||
|
||||
#[lang = "drop"]
|
||||
pub trait Drop {
|
||||
fn drop(&mut self);
|
||||
|
|
|
@ -250,7 +250,6 @@ language_item_table! {
|
|||
FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, Target::Struct, GenericRequirement::None;
|
||||
|
||||
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
|
||||
BoxFree, sym::box_free, box_free_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -123,12 +123,6 @@
|
|||
//! pointers to these functions even if they never get called anywhere. This can
|
||||
//! be seen as a special case of taking a function reference.
|
||||
//!
|
||||
//! #### Boxes
|
||||
//! Since `Box` expression have special compiler support, no explicit calls to
|
||||
//! `exchange_malloc()` and `box_free()` may show up in MIR, even if the
|
||||
//! compiler will generate them. We have to observe `Rvalue::Box` expressions
|
||||
//! and Box-typed drop-statements for that purpose.
|
||||
//!
|
||||
//!
|
||||
//! Interaction with Cross-Crate Inlining
|
||||
//! -------------------------------------
|
||||
|
|
|
@ -432,7 +432,6 @@ symbols! {
|
|||
bool,
|
||||
borrowck_graphviz_format,
|
||||
borrowck_graphviz_postflow,
|
||||
box_free,
|
||||
box_new,
|
||||
box_patterns,
|
||||
box_syntax,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue