diff options
Diffstat (limited to 'rust/alloc/boxed.rs')
-rw-r--r-- | rust/alloc/boxed.rs | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs index bdab710f7737..9620eba17268 100644 --- a/rust/alloc/boxed.rs +++ b/rust/alloc/boxed.rs @@ -159,12 +159,12 @@ use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; use core::marker::Tuple; use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, }; use core::pin::Pin; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull, Unique}; use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))] @@ -483,8 +483,12 @@ impl<T, A: Allocator> Box<T, A> { where A: Allocator, { - let layout = Layout::new::<mem::MaybeUninit<T>>(); - let ptr = alloc.allocate(layout)?.cast(); + let ptr = if T::IS_ZST { + NonNull::dangling() + } else { + let layout = Layout::new::<mem::MaybeUninit<T>>(); + alloc.allocate(layout)?.cast() + }; unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } @@ -553,8 +557,12 @@ impl<T, A: Allocator> Box<T, A> { where A: Allocator, { - let layout = Layout::new::<mem::MaybeUninit<T>>(); - let ptr = alloc.allocate_zeroed(layout)?.cast(); + let ptr = if T::IS_ZST { + NonNull::dangling() + } else { + let layout = Layout::new::<mem::MaybeUninit<T>>(); + alloc.allocate_zeroed(layout)?.cast() + }; unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } @@ -679,14 +687,16 @@ impl<T> Box<[T]> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_uninit_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> { - unsafe { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; - let ptr = Global.allocate(layout)?; - Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) - } + Global.allocate(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } /// Constructs a new boxed slice with uninitialized contents, with the memory @@ -711,14 +721,16 @@ impl<T> Box<[T]> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_zeroed_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> { - unsafe { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; - let ptr = Global.allocate_zeroed(layout)?; - Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) - } + Global.allocate_zeroed(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } } @@ -1223,7 +1235,9 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> { unsafe { let layout = Layout::for_value_raw(ptr.as_ptr()); - self.1.deallocate(From::from(ptr.cast()), layout) + if layout.size() != 0 { + self.1.deallocate(From::from(ptr.cast()), layout); + } } } } @@ -2173,7 +2187,7 @@ impl dyn Error + Send { let err: Box<dyn Error> = self; <dyn Error>::downcast(err).map_err(|s| unsafe { // Reapply the `Send` marker. - mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s) + Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send)) }) } } @@ -2187,7 +2201,7 @@ impl dyn Error + Send + Sync { let err: Box<dyn Error> = self; <dyn Error>::downcast(err).map_err(|s| unsafe { // Reapply the `Send + Sync` marker. - mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s) + Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send + Sync)) }) } } |