diff options
Diffstat (limited to 'library/alloc/src/boxed.rs')
| -rw-r--r-- | library/alloc/src/boxed.rs | 222 |
1 files changed, 112 insertions, 110 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 4536f555443..c84799bc83c 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1098,115 +1098,6 @@ impl<T: ?Sized> Box<T> { pub unsafe fn from_non_null(ptr: NonNull<T>) -> Self { unsafe { Self::from_raw(ptr.as_ptr()) } } -} - -impl<T: ?Sized, A: Allocator> Box<T, A> { - /// Constructs a box from a raw pointer in the given allocator. - /// - /// After calling this function, the raw pointer is owned by the - /// resulting `Box`. Specifically, the `Box` destructor will call - /// the destructor of `T` and free the allocated memory. For this - /// to be safe, the memory must have been allocated in accordance - /// with the [memory layout] used by `Box` . - /// - /// # Safety - /// - /// This function is unsafe because improper use may lead to - /// memory problems. For example, a double-free may occur if the - /// function is called twice on the same raw pointer. - /// - /// The raw pointer must point to a block of memory allocated by `alloc`. - /// - /// # Examples - /// - /// Recreate a `Box` which was previously converted to a raw pointer - /// using [`Box::into_raw_with_allocator`]: - /// ``` - /// #![feature(allocator_api)] - /// - /// use std::alloc::System; - /// - /// let x = Box::new_in(5, System); - /// let (ptr, alloc) = Box::into_raw_with_allocator(x); - /// let x = unsafe { Box::from_raw_in(ptr, alloc) }; - /// ``` - /// Manually create a `Box` from scratch by using the system allocator: - /// ``` - /// #![feature(allocator_api, slice_ptr_get)] - /// - /// use std::alloc::{Allocator, Layout, System}; - /// - /// unsafe { - /// let ptr = System.allocate(Layout::new::<i32>())?.as_mut_ptr() as *mut i32; - /// // In general .write is required to avoid attempting to destruct - /// // the (uninitialized) previous contents of `ptr`, though for this - /// // simple example `*ptr = 5` would have worked as well. - /// ptr.write(5); - /// let x = Box::from_raw_in(ptr, System); - /// } - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - /// - /// [memory layout]: self#memory-layout - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { - Box(unsafe { Unique::new_unchecked(raw) }, alloc) - } - - /// Constructs a box from a `NonNull` pointer in the given allocator. - /// - /// After calling this function, the `NonNull` pointer is owned by - /// the resulting `Box`. Specifically, the `Box` destructor will call - /// the destructor of `T` and free the allocated memory. For this - /// to be safe, the memory must have been allocated in accordance - /// with the [memory layout] used by `Box` . - /// - /// # Safety - /// - /// This function is unsafe because improper use may lead to - /// memory problems. For example, a double-free may occur if the - /// function is called twice on the same raw pointer. - /// - /// The non-null pointer must point to a block of memory allocated by `alloc`. - /// - /// # Examples - /// - /// Recreate a `Box` which was previously converted to a `NonNull` pointer - /// using [`Box::into_non_null_with_allocator`]: - /// ``` - /// #![feature(allocator_api, box_vec_non_null)] - /// - /// use std::alloc::System; - /// - /// let x = Box::new_in(5, System); - /// let (non_null, alloc) = Box::into_non_null_with_allocator(x); - /// let x = unsafe { Box::from_non_null_in(non_null, alloc) }; - /// ``` - /// Manually create a `Box` from scratch by using the system allocator: - /// ``` - /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)] - /// - /// use std::alloc::{Allocator, Layout, System}; - /// - /// unsafe { - /// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>(); - /// // In general .write is required to avoid attempting to destruct - /// // the (uninitialized) previous contents of `non_null`. - /// non_null.write(5); - /// let x = Box::from_non_null_in(non_null, System); - /// } - /// # Ok::<(), std::alloc::AllocError>(()) - /// ``` - /// - /// [memory layout]: self#memory-layout - #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] - #[inline] - pub unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self { - // SAFETY: guaranteed by the caller. - unsafe { Box::from_raw_in(raw.as_ptr(), alloc) } - } /// Consumes the `Box`, returning a wrapped raw pointer. /// @@ -1322,6 +1213,115 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { // SAFETY: `Box` is guaranteed to be non-null. unsafe { NonNull::new_unchecked(Self::into_raw(b)) } } +} + +impl<T: ?Sized, A: Allocator> Box<T, A> { + /// Constructs a box from a raw pointer in the given allocator. + /// + /// After calling this function, the raw pointer is owned by the + /// resulting `Box`. Specifically, the `Box` destructor will call + /// the destructor of `T` and free the allocated memory. For this + /// to be safe, the memory must have been allocated in accordance + /// with the [memory layout] used by `Box` . + /// + /// # Safety + /// + /// This function is unsafe because improper use may lead to + /// memory problems. For example, a double-free may occur if the + /// function is called twice on the same raw pointer. + /// + /// The raw pointer must point to a block of memory allocated by `alloc`. + /// + /// # Examples + /// + /// Recreate a `Box` which was previously converted to a raw pointer + /// using [`Box::into_raw_with_allocator`]: + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// let x = Box::new_in(5, System); + /// let (ptr, alloc) = Box::into_raw_with_allocator(x); + /// let x = unsafe { Box::from_raw_in(ptr, alloc) }; + /// ``` + /// Manually create a `Box` from scratch by using the system allocator: + /// ``` + /// #![feature(allocator_api, slice_ptr_get)] + /// + /// use std::alloc::{Allocator, Layout, System}; + /// + /// unsafe { + /// let ptr = System.allocate(Layout::new::<i32>())?.as_mut_ptr() as *mut i32; + /// // In general .write is required to avoid attempting to destruct + /// // the (uninitialized) previous contents of `ptr`, though for this + /// // simple example `*ptr = 5` would have worked as well. + /// ptr.write(5); + /// let x = Box::from_raw_in(ptr, System); + /// } + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [memory layout]: self#memory-layout + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + Box(unsafe { Unique::new_unchecked(raw) }, alloc) + } + + /// Constructs a box from a `NonNull` pointer in the given allocator. + /// + /// After calling this function, the `NonNull` pointer is owned by + /// the resulting `Box`. Specifically, the `Box` destructor will call + /// the destructor of `T` and free the allocated memory. For this + /// to be safe, the memory must have been allocated in accordance + /// with the [memory layout] used by `Box` . + /// + /// # Safety + /// + /// This function is unsafe because improper use may lead to + /// memory problems. For example, a double-free may occur if the + /// function is called twice on the same raw pointer. + /// + /// The non-null pointer must point to a block of memory allocated by `alloc`. + /// + /// # Examples + /// + /// Recreate a `Box` which was previously converted to a `NonNull` pointer + /// using [`Box::into_non_null_with_allocator`]: + /// ``` + /// #![feature(allocator_api, box_vec_non_null)] + /// + /// use std::alloc::System; + /// + /// let x = Box::new_in(5, System); + /// let (non_null, alloc) = Box::into_non_null_with_allocator(x); + /// let x = unsafe { Box::from_non_null_in(non_null, alloc) }; + /// ``` + /// Manually create a `Box` from scratch by using the system allocator: + /// ``` + /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)] + /// + /// use std::alloc::{Allocator, Layout, System}; + /// + /// unsafe { + /// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>(); + /// // In general .write is required to avoid attempting to destruct + /// // the (uninitialized) previous contents of `non_null`. + /// non_null.write(5); + /// let x = Box::from_non_null_in(non_null, System); + /// } + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [memory layout]: self#memory-layout + #[unstable(feature = "allocator_api", issue = "32838")] + // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[inline] + pub unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self { + // SAFETY: guaranteed by the caller. + unsafe { Box::from_raw_in(raw.as_ptr(), alloc) } + } /// Consumes the `Box`, returning a wrapped raw pointer and the allocator. /// @@ -1602,7 +1602,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { where A: 'a, { - unsafe { &mut *Box::into_raw(b) } + let (ptr, alloc) = Box::into_raw_with_allocator(b); + mem::forget(alloc); + unsafe { &mut *ptr } } /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then |
