Skip to content

Commit bd8c177

Browse files
committed
Switch box_free to take the destructured contents of Box
As of now, Box only contains a Unique pointer, so this is the sole argument to box_free. Consequently, we remove the code supporting the previous box_free signature. We however keep the old definition for bootstrapping purpose.
1 parent 64f5233 commit bd8c177

File tree

4 files changed

+29
-56
lines changed

4 files changed

+29
-56
lines changed

src/liballoc/alloc.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
issue = "32838")]
1717

1818
use core::intrinsics::{min_align_of_val, size_of_val};
19-
use core::ptr::NonNull;
19+
use core::ptr::{NonNull, Unique};
2020
use core::usize;
2121

2222
#[doc(inline)]
@@ -170,9 +170,17 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
170170
}
171171
}
172172

173-
#[cfg_attr(not(test), lang = "box_free")]
173+
#[cfg(stage0)]
174+
#[lang = "box_free"]
175+
#[inline]
176+
unsafe fn old_box_free<T: ?Sized>(ptr: *mut T) {
177+
box_free(Unique::new_unchecked(ptr))
178+
}
179+
180+
#[cfg_attr(not(any(test, stage0)), lang = "box_free")]
174181
#[inline]
175-
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
182+
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
183+
let ptr = ptr.as_ptr();
176184
let size = size_of_val(&*ptr);
177185
let align = min_align_of_val(&*ptr);
178186
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.

src/liballoc/arc.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,8 @@ impl<T: ?Sized> Arc<T> {
566566

567567
fn from_box(v: Box<T>) -> Arc<T> {
568568
unsafe {
569-
let bptr = Box::into_raw(v);
569+
let box_unique = Box::into_unique(v);
570+
let bptr = box_unique.as_ptr();
570571

571572
let value_size = size_of_val(&*bptr);
572573
let ptr = Self::allocate_for_ptr(bptr);
@@ -578,7 +579,7 @@ impl<T: ?Sized> Arc<T> {
578579
value_size);
579580

580581
// Free the allocation without dropping its contents
581-
box_free(bptr);
582+
box_free(box_unique);
582583

583584
Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
584585
}

src/liballoc/rc.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,8 @@ impl<T: ?Sized> Rc<T> {
681681

682682
fn from_box(v: Box<T>) -> Rc<T> {
683683
unsafe {
684-
let bptr = Box::into_raw(v);
684+
let box_unique = Box::into_unique(v);
685+
let bptr = box_unique.as_ptr();
685686

686687
let value_size = size_of_val(&*bptr);
687688
let ptr = Self::allocate_for_ptr(bptr);
@@ -693,7 +694,7 @@ impl<T: ?Sized> Rc<T> {
693694
value_size);
694695

695696
// Free the allocation without dropping its contents
696-
box_free(bptr);
697+
box_free(box_unique);
697698

698699
Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
699700
}

src/librustc_mir/util/elaborate_drops.rs

+12-49
Original file line numberDiff line numberDiff line change
@@ -879,56 +879,19 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
879879
let tcx = self.tcx();
880880
let unit_temp = Place::Local(self.new_temp(tcx.mk_nil()));
881881
let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
882-
let free_sig = tcx.fn_sig(free_func).skip_binder().clone();
883-
let free_inputs = free_sig.inputs();
884-
// If the box_free function takes a *mut T, transform the Box into
885-
// such a pointer before calling box_free. Otherwise, pass it all
886-
// the fields in the Box as individual arguments.
887-
let (stmts, args) = if free_inputs.len() == 1 && free_inputs[0].is_mutable_pointer() {
888-
let ty = substs.type_at(0);
889-
let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut {
890-
ty: ty,
891-
mutbl: hir::Mutability::MutMutable
892-
});
893-
let ptr_ty = tcx.mk_mut_ptr(ty);
894-
let ref_tmp = Place::Local(self.new_temp(ref_ty));
895-
let ptr_tmp = Place::Local(self.new_temp(ptr_ty));
896-
let stmts = vec![
897-
self.assign(&ref_tmp, Rvalue::Ref(
898-
tcx.types.re_erased,
899-
BorrowKind::Mut { allow_two_phase_borrow: false },
900-
self.place.clone().deref()
901-
)),
902-
self.assign(&ptr_tmp, Rvalue::Cast(
903-
CastKind::Misc,
904-
Operand::Move(ref_tmp),
905-
ptr_ty,
906-
)),
907-
];
908-
(stmts, vec![Operand::Move(ptr_tmp)])
909-
} else {
910-
let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| {
911-
let field = Field::new(i);
912-
let field_ty = f.ty(self.tcx(), substs);
913-
Operand::Move(self.place.clone().field(field, field_ty))
914-
}).collect();
915-
(vec![], args)
916-
};
882+
let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| {
883+
let field = Field::new(i);
884+
let field_ty = f.ty(self.tcx(), substs);
885+
Operand::Move(self.place.clone().field(field, field_ty))
886+
}).collect();
917887

918-
let free_block = BasicBlockData {
919-
statements: stmts,
920-
terminator: Some(Terminator {
921-
kind: TerminatorKind::Call {
922-
func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
923-
args: args,
924-
destination: Some((unit_temp, target)),
925-
cleanup: None
926-
}, // FIXME(#43234)
927-
source_info: self.source_info,
928-
}),
929-
is_cleanup: unwind.is_cleanup()
930-
};
931-
let free_block = self.elaborator.patch().new_block(free_block);
888+
let call = TerminatorKind::Call {
889+
func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
890+
args: args,
891+
destination: Some((unit_temp, target)),
892+
cleanup: None
893+
}; // FIXME(#43234)
894+
let free_block = self.new_block(unwind, call);
932895

933896
let block_start = Location { block: free_block, statement_index: 0 };
934897
self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);

0 commit comments

Comments
 (0)