diff options
| author | bors <bors@rust-lang.org> | 2023-06-17 16:10:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-06-17 16:10:57 +0000 |
| commit | a8a29070f07e47a244c8199ad582f93172019743 (patch) | |
| tree | 763b2ef51eb7ab864c4f3bb635e1c8060d19361d /library/alloc/src | |
| parent | e1c29d137dd779dcfce447d8d149ee6b8e9bdf78 (diff) | |
| parent | a5c6cb888eac7ad8905a3902b985e412aaceb002 (diff) | |
| download | rust-a8a29070f07e47a244c8199ad582f93172019743.tar.gz rust-a8a29070f07e47a244c8199ad582f93172019743.zip | |
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.
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/alloc.rs | 7 | ||||
| -rw-r--r-- | library/alloc/src/boxed.rs | 10 | ||||
| -rw-r--r-- | library/alloc/src/rc.rs | 16 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 16 |
4 files changed, 28 insertions, 21 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 8c4f6a73d7f..e24a0fe51bd 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -4,8 +4,10 @@ #[cfg(not(test))] use core::intrinsics; +#[cfg(all(bootstrap, not(test)))] use core::intrinsics::{min_align_of_val, size_of_val}; +#[cfg(all(bootstrap, not(test)))] use core::ptr::Unique; #[cfg(not(test))] use core::ptr::{self, NonNull}; @@ -335,14 +337,15 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } } -#[cfg_attr(not(test), lang = "box_free")] +#[cfg(all(bootstrap, not(test)))] +#[lang = "box_free"] #[inline] // This signature has to be the same as `Box`, otherwise an ICE will happen. // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as // well. // For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`, // this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well. -pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) { +unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) { unsafe { let size = size_of_val(ptr.as_ref()); let align = min_align_of_val(ptr.as_ref()); diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1768687e8cd..8ef2bac9282 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1211,8 +1211,16 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> { + #[inline] fn drop(&mut self) { - // FIXME: Do nothing, drop is currently performed by compiler. + // the T in the Box is dropped by the compiler before the destructor is run + + let ptr = self.0; + + unsafe { + let layout = Layout::for_value_raw(ptr.as_ptr()); + self.1.deallocate(From::from(ptr.cast()), layout) + } } } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 38a711ac750..34d3acae546 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -270,7 +270,7 @@ use core::slice::from_raw_parts_mut; #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; #[cfg(not(no_global_oom_handling))] -use crate::alloc::{box_free, WriteCloneIntoRaw}; +use crate::alloc::WriteCloneIntoRaw; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::borrow::{Cow, ToOwned}; #[cfg(not(no_global_oom_handling))] @@ -1442,23 +1442,21 @@ impl<T: ?Sized> Rc<T> { } #[cfg(not(no_global_oom_handling))] - fn from_box(v: Box<T>) -> Rc<T> { + fn from_box(src: Box<T>) -> Rc<T> { unsafe { - let (box_unique, alloc) = Box::into_unique(v); - let bptr = box_unique.as_ptr(); - - let value_size = size_of_val(&*bptr); - let ptr = Self::allocate_for_ptr(bptr); + let value_size = size_of_val(&*src); + let ptr = Self::allocate_for_ptr(&*src); // Copy value as bytes ptr::copy_nonoverlapping( - bptr as *const T as *const u8, + &*src as *const T as *const u8, &mut (*ptr).value as *mut _ as *mut u8, value_size, ); // Free the allocation without dropping its contents - box_free(box_unique, alloc); + let src = Box::from_raw(Box::into_raw(src) as *mut mem::ManuallyDrop<T>); + drop(src); Self::from_ptr(ptr) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index bfdb7a92bef..d2c87cf705c 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -33,7 +33,7 @@ use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; #[cfg(not(no_global_oom_handling))] -use crate::alloc::{box_free, WriteCloneIntoRaw}; +use crate::alloc::WriteCloneIntoRaw; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; @@ -1360,23 +1360,21 @@ impl<T: ?Sized> Arc<T> { } #[cfg(not(no_global_oom_handling))] - fn from_box(v: Box<T>) -> Arc<T> { + fn from_box(src: Box<T>) -> Arc<T> { unsafe { - let (box_unique, alloc) = Box::into_unique(v); - let bptr = box_unique.as_ptr(); - - let value_size = size_of_val(&*bptr); - let ptr = Self::allocate_for_ptr(bptr); + let value_size = size_of_val(&*src); + let ptr = Self::allocate_for_ptr(&*src); // Copy value as bytes ptr::copy_nonoverlapping( - bptr as *const T as *const u8, + &*src as *const T as *const u8, &mut (*ptr).data as *mut _ as *mut u8, value_size, ); // Free the allocation without dropping its contents - box_free(box_unique, alloc); + let src = Box::from_raw(Box::into_raw(src) as *mut mem::ManuallyDrop<T>); + drop(src); Self::from_ptr(ptr) } |
