Skip to content

Commit 88cc9c4

Browse files
committed
Auto merge of rust-lang#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.
2 parents a507556 + da973f3 commit 88cc9c4

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

alloc/src/alloc.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
#[cfg(not(test))]
66
use core::intrinsics;
7+
#[cfg(all(bootstrap, not(test)))]
78
use core::intrinsics::{min_align_of_val, size_of_val};
89

10+
#[cfg(all(bootstrap, not(test)))]
911
use core::ptr::Unique;
1012
#[cfg(not(test))]
1113
use core::ptr::{self, NonNull};
@@ -335,14 +337,15 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
335337
}
336338
}
337339

338-
#[cfg_attr(not(test), lang = "box_free")]
340+
#[cfg(all(bootstrap, not(test)))]
341+
#[lang = "box_free"]
339342
#[inline]
340343
// This signature has to be the same as `Box`, otherwise an ICE will happen.
341344
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
342345
// well.
343346
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
344347
// this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
345-
pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
348+
unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
346349
unsafe {
347350
let size = size_of_val(ptr.as_ref());
348351
let align = min_align_of_val(ptr.as_ref());

alloc/src/boxed.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,8 +1211,16 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
12111211

12121212
#[stable(feature = "rust1", since = "1.0.0")]
12131213
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
1214+
#[inline]
12141215
fn drop(&mut self) {
1215-
// FIXME: Do nothing, drop is currently performed by compiler.
1216+
// the T in the Box is dropped by the compiler before the destructor is run
1217+
1218+
let ptr = self.0;
1219+
1220+
unsafe {
1221+
let layout = Layout::for_value_raw(ptr.as_ptr());
1222+
self.1.deallocate(From::from(ptr.cast()), layout)
1223+
}
12161224
}
12171225
}
12181226

alloc/src/rc.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ use core::slice::from_raw_parts_mut;
270270
#[cfg(not(no_global_oom_handling))]
271271
use crate::alloc::handle_alloc_error;
272272
#[cfg(not(no_global_oom_handling))]
273-
use crate::alloc::{box_free, WriteCloneIntoRaw};
273+
use crate::alloc::WriteCloneIntoRaw;
274274
use crate::alloc::{AllocError, Allocator, Global, Layout};
275275
use crate::borrow::{Cow, ToOwned};
276276
#[cfg(not(no_global_oom_handling))]
@@ -1442,23 +1442,21 @@ impl<T: ?Sized> Rc<T> {
14421442
}
14431443

14441444
#[cfg(not(no_global_oom_handling))]
1445-
fn from_box(v: Box<T>) -> Rc<T> {
1445+
fn from_box(src: Box<T>) -> Rc<T> {
14461446
unsafe {
1447-
let (box_unique, alloc) = Box::into_unique(v);
1448-
let bptr = box_unique.as_ptr();
1449-
1450-
let value_size = size_of_val(&*bptr);
1451-
let ptr = Self::allocate_for_ptr(bptr);
1447+
let value_size = size_of_val(&*src);
1448+
let ptr = Self::allocate_for_ptr(&*src);
14521449

14531450
// Copy value as bytes
14541451
ptr::copy_nonoverlapping(
1455-
bptr as *const T as *const u8,
1452+
&*src as *const T as *const u8,
14561453
&mut (*ptr).value as *mut _ as *mut u8,
14571454
value_size,
14581455
);
14591456

14601457
// Free the allocation without dropping its contents
1461-
box_free(box_unique, alloc);
1458+
let src = Box::from_raw(Box::into_raw(src) as *mut mem::ManuallyDrop<T>);
1459+
drop(src);
14621460

14631461
Self::from_ptr(ptr)
14641462
}

alloc/src/sync.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use core::sync::atomic::Ordering::{Acquire, Relaxed, Release};
3333
#[cfg(not(no_global_oom_handling))]
3434
use crate::alloc::handle_alloc_error;
3535
#[cfg(not(no_global_oom_handling))]
36-
use crate::alloc::{box_free, WriteCloneIntoRaw};
36+
use crate::alloc::WriteCloneIntoRaw;
3737
use crate::alloc::{AllocError, Allocator, Global, Layout};
3838
use crate::borrow::{Cow, ToOwned};
3939
use crate::boxed::Box;
@@ -1360,23 +1360,21 @@ impl<T: ?Sized> Arc<T> {
13601360
}
13611361

13621362
#[cfg(not(no_global_oom_handling))]
1363-
fn from_box(v: Box<T>) -> Arc<T> {
1363+
fn from_box(src: Box<T>) -> Arc<T> {
13641364
unsafe {
1365-
let (box_unique, alloc) = Box::into_unique(v);
1366-
let bptr = box_unique.as_ptr();
1367-
1368-
let value_size = size_of_val(&*bptr);
1369-
let ptr = Self::allocate_for_ptr(bptr);
1365+
let value_size = size_of_val(&*src);
1366+
let ptr = Self::allocate_for_ptr(&*src);
13701367

13711368
// Copy value as bytes
13721369
ptr::copy_nonoverlapping(
1373-
bptr as *const T as *const u8,
1370+
&*src as *const T as *const u8,
13741371
&mut (*ptr).data as *mut _ as *mut u8,
13751372
value_size,
13761373
);
13771374

13781375
// Free the allocation without dropping its contents
1379-
box_free(box_unique, alloc);
1376+
let src = Box::from_raw(Box::into_raw(src) as *mut mem::ManuallyDrop<T>);
1377+
drop(src);
13801378

13811379
Self::from_ptr(ptr)
13821380
}

0 commit comments

Comments
 (0)