//! The `Box` type for heap allocation. //! //! [`Box`], casually referred to as a 'box', provides the simplest form of //! heap allocation in Rust. Boxes provide ownership for this allocation, and //! drop their contents when they go out of scope. Boxes also ensure that they //! never allocate more than `isize::MAX` bytes. //! //! # Examples //! //! Move a value from the stack to the heap by creating a [`Box`]: //! //! ``` //! let val: u8 = 5; //! let boxed: Box = Box::new(val); //! ``` //! //! Move a value from a [`Box`] back to the stack by [dereferencing]: //! //! ``` //! let boxed: Box = Box::new(5); //! let val: u8 = *boxed; //! ``` //! //! Creating a recursive data structure: //! //! ``` //! # #[allow(dead_code)] //! #[derive(Debug)] //! enum List { //! Cons(T, Box>), //! Nil, //! } //! //! let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); //! println!("{list:?}"); //! ``` //! //! This will print `Cons(1, Cons(2, Nil))`. //! //! Recursive structures must be boxed, because if the definition of `Cons` //! looked like this: //! //! ```compile_fail,E0072 //! # enum List { //! Cons(T, List), //! # } //! ``` //! //! It wouldn't work. This is because the size of a `List` depends on how many //! elements are in the list, and so we don't know how much memory to allocate //! for a `Cons`. By introducing a [`Box`], which has a defined size, we know how //! big `Cons` needs to be. //! //! # Memory layout //! //! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for its allocation. It is //! valid to convert both ways between a [`Box`] and a raw pointer allocated with the [`Global`] //! allocator, given that the [`Layout`] used with the allocator is correct for the type and the raw //! pointer points to a valid value of the right type. More precisely, a `value: *mut T` that has //! been allocated with the [`Global`] allocator with `Layout::for_value(&*value)` may be converted //! into a box using [`Box::::from_raw(value)`]. Conversely, the memory backing a `value: *mut T` //! obtained from [`Box::::into_raw`] may be deallocated using the [`Global`] allocator with //! [`Layout::for_value(&*value)`]. //! //! For zero-sized values, the `Box` pointer has to be non-null and sufficiently aligned. The //! recommended way to build a Box to a ZST if `Box::new` cannot be used is to use //! [`ptr::NonNull::dangling`]. //! //! On top of these basic layout requirements, a `Box` must point to a valid value of `T`. //! //! So long as `T: Sized`, a `Box` is guaranteed to be represented //! as a single pointer and is also ABI-compatible with C pointers //! (i.e. the C type `T*`). This means that if you have extern "C" //! Rust functions that will be called from C, you can define those //! Rust functions using `Box` types, and use `T*` as corresponding //! type on the C side. As an example, consider this C header which //! declares functions that create and destroy some kind of `Foo` //! value: //! //! ```c //! /* C header */ //! //! /* Returns ownership to the caller */ //! struct Foo* foo_new(void); //! //! /* Takes ownership from the caller; no-op when invoked with null */ //! void foo_delete(struct Foo*); //! ``` //! //! These two functions might be implemented in Rust as follows. Here, the //! `struct Foo*` type from C is translated to `Box`, which captures //! the ownership constraints. Note also that the nullable argument to //! `foo_delete` is represented in Rust as `Option>`, since `Box` //! cannot be null. //! //! ``` //! #[repr(C)] //! pub struct Foo; //! //! #[unsafe(no_mangle)] //! pub extern "C" fn foo_new() -> Box { //! Box::new(Foo) //! } //! //! #[unsafe(no_mangle)] //! pub extern "C" fn foo_delete(_: Option>) {} //! ``` //! //! Even though `Box` has the same representation and C ABI as a C pointer, //! this does not mean that you can convert an arbitrary `T*` into a `Box` //! and expect things to work. `Box` values will always be fully aligned, //! non-null pointers. Moreover, the destructor for `Box` will attempt to //! free the value with the global allocator. In general, the best practice //! is to only use `Box` for pointers that originated from the global //! allocator. //! //! **Important.** At least at present, you should avoid using //! `Box` types for functions that are defined in C but invoked //! from Rust. In those cases, you should directly mirror the C types //! as closely as possible. Using types like `Box` where the C //! definition is just using `T*` can lead to undefined behavior, as //! described in [rust-lang/unsafe-code-guidelines#198][ucg#198]. //! //! # Considerations for unsafe code //! //! **Warning: This section is not normative and is subject to change, possibly //! being relaxed in the future! It is a simplified summary of the rules //! currently implemented in the compiler.** //! //! The aliasing rules for `Box` are the same as for `&mut T`. `Box` //! asserts uniqueness over its content. Using raw pointers derived from a box //! after that box has been mutated through, moved or borrowed as `&mut T` //! is not allowed. For more guidance on working with box from unsafe code, see //! [rust-lang/unsafe-code-guidelines#326][ucg#326]. //! //! # Editions //! //! A special case exists for the implementation of `IntoIterator` for arrays on the Rust 2021 //! edition, as documented [here][array]. Unfortunately, it was later found that a similar //! workaround should be added for boxed slices, and this was applied in the 2024 edition. //! //! Specifically, `IntoIterator` is implemented for `Box<[T]>` on all editions, but specific calls //! to `into_iter()` for boxed slices will defer to the slice implementation on editions before //! 2024: //! //! ```rust,edition2021 //! // Rust 2015, 2018, and 2021: //! //! # #![allow(boxed_slice_into_iter)] // override our `deny(warnings)` //! let boxed_slice: Box<[i32]> = vec![0; 3].into_boxed_slice(); //! //! // This creates a slice iterator, producing references to each value. //! for item in boxed_slice.into_iter().enumerate() { //! let (i, x): (usize, &i32) = item; //! println!("boxed_slice[{i}] = {x}"); //! } //! //! // The `boxed_slice_into_iter` lint suggests this change for future compatibility: //! for item in boxed_slice.iter().enumerate() { //! let (i, x): (usize, &i32) = item; //! println!("boxed_slice[{i}] = {x}"); //! } //! //! // You can explicitly iterate a boxed slice by value using `IntoIterator::into_iter` //! for item in IntoIterator::into_iter(boxed_slice).enumerate() { //! let (i, x): (usize, i32) = item; //! println!("boxed_slice[{i}] = {x}"); //! } //! ``` //! //! Similar to the array implementation, this may be modified in the future to remove this override, //! and it's best to avoid relying on this edition-dependent behavior if you wish to preserve //! compatibility with future versions of the compiler. //! //! [ucg#198]: https://github.com/rust-lang/unsafe-code-guidelines/issues/198 //! [ucg#326]: https://github.com/rust-lang/unsafe-code-guidelines/issues/326 //! [dereferencing]: core::ops::Deref //! [`Box::::from_raw(value)`]: Box::from_raw //! [`Global`]: crate::alloc::Global //! [`Layout`]: crate::alloc::Layout //! [`Layout::for_value(&*value)`]: crate::alloc::Layout::for_value //! [valid]: ptr#safety #![stable(feature = "rust1", since = "1.0.0")] use core::borrow::{Borrow, BorrowMut}; #[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; use core::cmp::Ordering; use core::error::{self, Error}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; use core::marker::{Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver, }; use core::pin::{Pin, PinCoerceUnsized}; use core::ptr::{self, NonNull, Unique}; use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::raw_vec::RawVec; #[cfg(not(no_global_oom_handling))] use crate::str::from_boxed_utf8_unchecked; /// Conversion related impls for `Box<_>` (`From`, `downcast`, etc) mod convert; /// Iterator related impls for `Box<_>`. mod iter; /// [`ThinBox`] implementation. mod thin; #[unstable(feature = "thin_box", issue = "92791")] pub use thin::ThinBox; /// A pointer type that uniquely owns a heap allocation of type `T`. /// /// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] #[fundamental] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] #[doc(search_unbox)] // The declaration of the `Box` struct must be kept in sync with the // compiler or ICEs will happen. pub struct Box< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, >(Unique, A); /// Constructs a `Box` by calling the `exchange_malloc` lang item and moving the argument into /// the newly allocated memory. This is an intrinsic to avoid unnecessary copies. /// /// This is the surface syntax for `box ` expressions. #[rustc_intrinsic] #[unstable(feature = "liballoc_internals", issue = "none")] pub fn box_new(x: T) -> Box; impl Box { /// Allocates memory on the heap and then places `x` into it. /// /// This doesn't actually allocate if `T` is zero-sized. /// /// # Examples /// /// ``` /// let five = Box::new(5); /// ``` #[cfg(not(no_global_oom_handling))] #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[rustc_diagnostic_item = "box_new"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn new(x: T) -> Self { return box_new(x); } /// Constructs a new box with uninitialized contents. /// /// # Examples /// /// ``` /// let mut five = Box::::new_uninit(); /// // Deferred initialization: /// five.write(5); /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] #[inline] pub fn new_uninit() -> Box> { Self::new_uninit_in(Global) } /// Constructs a new `Box` with uninitialized contents, with the memory /// being filled with `0` bytes. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(new_zeroed_alloc)] /// /// let zero = Box::::new_zeroed(); /// let zero = unsafe { zero.assume_init() }; /// /// assert_eq!(*zero, 0) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed() -> Box> { Self::new_zeroed_in(Global) } /// Constructs a new `Pin>`. If `T` does not implement [`Unpin`], then /// `x` will be pinned in memory and unable to be moved. /// /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin(x)` /// does the same as [Box::into_pin]\([Box::new]\(x)). Consider using /// [`into_pin`](Box::into_pin) if you already have a `Box`, or if you want to /// construct a (pinned) `Box` in a different way than with [`Box::new`]. #[cfg(not(no_global_oom_handling))] #[stable(feature = "pin", since = "1.33.0")] #[must_use] #[inline(always)] pub fn pin(x: T) -> Pin> { Box::new(x).into() } /// Allocates memory on the heap then places `x` into it, /// returning an error if the allocation fails /// /// This doesn't actually allocate if `T` is zero-sized. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// let five = Box::try_new(5)?; /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new(x: T) -> Result { Self::try_new_in(x, Global) } /// Constructs a new box with uninitialized contents on the heap, /// returning an error if the allocation fails /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// let mut five = Box::::try_new_uninit()?; /// // Deferred initialization: /// five.write(5); /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_uninit() -> Result>, AllocError> { Box::try_new_uninit_in(Global) } /// Constructs a new `Box` with uninitialized contents, with the memory /// being filled with `0` bytes on the heap /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// let zero = Box::::try_new_zeroed()?; /// let zero = unsafe { zero.assume_init() }; /// /// assert_eq!(*zero, 0); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_zeroed() -> Result>, AllocError> { Box::try_new_zeroed_in(Global) } } impl Box { /// Allocates memory in the given allocator then places `x` into it. /// /// This doesn't actually allocate if `T` is zero-sized. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let five = Box::new_in(5, System); /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] #[inline] pub fn new_in(x: T, alloc: A) -> Self where A: Allocator, { let mut boxed = Self::new_uninit_in(alloc); boxed.write(x); unsafe { boxed.assume_init() } } /// Allocates memory in the given allocator then places `x` into it, /// returning an error if the allocation fails /// /// This doesn't actually allocate if `T` is zero-sized. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let five = Box::try_new_in(5, System)?; /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_in(x: T, alloc: A) -> Result where A: Allocator, { let mut boxed = Self::try_new_uninit_in(alloc)?; boxed.write(x); unsafe { Ok(boxed.assume_init()) } } /// Constructs a new box with uninitialized contents in the provided allocator. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let mut five = Box::::new_uninit_in(System); /// // Deferred initialization: /// five.write(5); /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit_in(alloc: A) -> Box, A> where A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. // That would make code size bigger. match Box::try_new_uninit_in(alloc) { Ok(m) => m, Err(_) => handle_alloc_error(layout), } } /// Constructs a new box with uninitialized contents in the provided allocator, /// returning an error if the allocation fails /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let mut five = Box::::try_new_uninit_in(System)?; /// // Deferred initialization: /// five.write(5); /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> where A: Allocator, { let ptr = if T::IS_ZST { NonNull::dangling() } else { let layout = Layout::new::>(); alloc.allocate(layout)?.cast() }; unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } /// Constructs a new `Box` with uninitialized contents, with the memory /// being filled with `0` bytes in the provided allocator. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let zero = Box::::new_zeroed_in(System); /// let zero = unsafe { zero.assume_init() }; /// /// assert_eq!(*zero, 0) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] #[cfg(not(no_global_oom_handling))] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_in(alloc: A) -> Box, A> where A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. // That would make code size bigger. match Box::try_new_zeroed_in(alloc) { Ok(m) => m, Err(_) => handle_alloc_error(layout), } } /// Constructs a new `Box` with uninitialized contents, with the memory /// being filled with `0` bytes in the provided allocator, /// returning an error if the allocation fails, /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let zero = Box::::try_new_zeroed_in(System)?; /// let zero = unsafe { zero.assume_init() }; /// /// assert_eq!(*zero, 0); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> where A: Allocator, { let ptr = if T::IS_ZST { NonNull::dangling() } else { let layout = Layout::new::>(); alloc.allocate_zeroed(layout)?.cast() }; unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } /// Constructs a new `Pin>`. If `T` does not implement [`Unpin`], then /// `x` will be pinned in memory and unable to be moved. /// /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin_in(x, alloc)` /// does the same as [Box::into_pin]\([Box::new_in]\(x, alloc)). Consider using /// [`into_pin`](Box::into_pin) if you already have a `Box`, or if you want to /// construct a (pinned) `Box` in a different way than with [`Box::new_in`]. #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] #[inline(always)] pub fn pin_in(x: T, alloc: A) -> Pin where A: 'static + Allocator, { Self::into_pin(Self::new_in(x, alloc)) } /// Converts a `Box` into a `Box<[T]>` /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } /// Consumes the `Box`, returning the wrapped value. /// /// # Examples /// /// ``` /// #![feature(box_into_inner)] /// /// let c = Box::new(5); /// /// assert_eq!(Box::into_inner(c), 5); /// ``` #[unstable(feature = "box_into_inner", issue = "80437")] #[inline] pub fn into_inner(boxed: Self) -> T { *boxed } } impl Box<[T]> { /// Constructs a new boxed slice with uninitialized contents. /// /// # Examples /// /// ``` /// let mut values = Box::<[u32]>::new_uninit_slice(3); /// // Deferred initialization: /// values[0].write(1); /// values[1].write(2); /// values[2].write(3); /// let values = unsafe {values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity(len).into_box(len) } } /// Constructs a new boxed slice with uninitialized contents, with the memory /// being filled with `0` bytes. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(new_zeroed_alloc)] /// /// let values = Box::<[u32]>::new_zeroed_slice(3); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "new_zeroed_alloc", issue = "129396")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } } /// Constructs a new boxed slice with uninitialized contents. Returns an error if /// the allocation fails. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?; /// // Deferred initialization: /// values[0].write(1); /// values[1].write(2); /// values[2].write(3); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_uninit_slice(len: usize) -> Result]>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { let layout = match Layout::array::>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; 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 /// being filled with `0` bytes. Returns an error if the allocation fails. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?; /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_zeroed_slice(len: usize) -> Result]>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { let layout = match Layout::array::>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; Global.allocate_zeroed(layout)?.cast() }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } /// Converts the boxed slice into a boxed array. /// /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] pub fn into_array(self) -> Option> { if self.len() == N { let ptr = Self::into_raw(self) as *mut [T; N]; // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. let me = unsafe { Box::from_raw(ptr) }; Some(me) } else { None } } } impl Box<[T], A> { /// Constructs a new boxed slice with uninitialized contents in the provided allocator. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, System); /// // Deferred initialization: /// values[0].write(1); /// values[1].write(2); /// values[2].write(3); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } } /// Constructs a new boxed slice with uninitialized contents in the provided allocator, /// with the memory being filled with `0` bytes. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let values = Box::<[u32], _>::new_zeroed_slice_in(3, System); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } } /// Constructs a new boxed slice with uninitialized contents in the provided allocator. Returns an error if /// the allocation fails. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let mut values = Box::<[u32], _>::try_new_uninit_slice_in(3, System)?; /// // Deferred initialization: /// values[0].write(1); /// values[1].write(2); /// values[2].write(3); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_uninit_slice_in( len: usize, alloc: A, ) -> Result], A>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { let layout = match Layout::array::>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; alloc.allocate(layout)?.cast() }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } /// Constructs a new boxed slice with uninitialized contents in the provided allocator, with the memory /// being filled with `0` bytes. Returns an error if the allocation fails. /// /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage /// of this method. /// /// # Examples /// /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let values = Box::<[u32], _>::try_new_zeroed_slice_in(3, System)?; /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_zeroed_slice_in( len: usize, alloc: A, ) -> Result], A>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { let layout = match Layout::array::>(len) { Ok(l) => l, Err(_) => return Err(AllocError), }; alloc.allocate_zeroed(layout)?.cast() }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } } impl Box, A> { /// Converts to `Box`. /// /// # Safety /// /// As with [`MaybeUninit::assume_init`], /// it is up to the caller to guarantee that the value /// really is in an initialized state. /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// /// ``` /// let mut five = Box::::new_uninit(); /// // Deferred initialization: /// five.write(5); /// let five: Box = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] #[inline] pub unsafe fn assume_init(self) -> Box { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } /// Writes the value and converts to `Box`. /// /// This method converts the box similarly to [`Box::assume_init`] but /// writes `value` into it before conversion thus guaranteeing safety. /// In some scenarios use of this method may improve performance because /// the compiler may be able to optimize copying from stack. /// /// # Examples /// /// ``` /// let big_box = Box::<[usize; 1024]>::new_uninit(); /// /// let mut array = [0; 1024]; /// for (i, place) in array.iter_mut().enumerate() { /// *place = i; /// } /// /// // The optimizer may be able to elide this copy, so previous code writes /// // to heap directly. /// let big_box = Box::write(big_box, array); /// /// for (i, x) in big_box.iter().enumerate() { /// assert_eq!(*x, i); /// } /// ``` #[stable(feature = "box_uninit_write", since = "1.87.0")] #[inline] pub fn write(mut boxed: Self, value: T) -> Box { unsafe { (*boxed).write(value); boxed.assume_init() } } } impl Box<[mem::MaybeUninit], A> { /// Converts to `Box<[T], A>`. /// /// # Safety /// /// As with [`MaybeUninit::assume_init`], /// it is up to the caller to guarantee that the values /// really are in an initialized state. /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// /// ``` /// let mut values = Box::<[u32]>::new_uninit_slice(3); /// // Deferred initialization: /// values[0].write(1); /// values[1].write(2); /// values[2].write(3); /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] #[inline] pub unsafe fn assume_init(self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut [T], alloc) } } } impl Box { /// Constructs a box from a raw pointer. /// /// 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 the global allocator. /// /// The safety conditions are described in the [memory layout] section. /// /// # Examples /// /// Recreate a `Box` which was previously converted to a raw pointer /// using [`Box::into_raw`]: /// ``` /// let x = Box::new(5); /// let ptr = Box::into_raw(x); /// let x = unsafe { Box::from_raw(ptr) }; /// ``` /// Manually create a `Box` from scratch by using the global allocator: /// ``` /// use std::alloc::{alloc, Layout}; /// /// unsafe { /// let ptr = alloc(Layout::new::()) 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(ptr); /// } /// ``` /// /// [memory layout]: self#memory-layout #[stable(feature = "box_raw", since = "1.4.0")] #[inline] #[must_use = "call `drop(Box::from_raw(ptr))` if you intend to drop the `Box`"] pub unsafe fn from_raw(raw: *mut T) -> Self { unsafe { Self::from_raw_in(raw, Global) } } /// Constructs a box from a `NonNull` pointer. /// /// 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 `NonNull` pointer. /// /// The non-null pointer must point to a block of memory allocated by the global allocator. /// /// The safety conditions are described in the [memory layout] section. /// /// # Examples /// /// Recreate a `Box` which was previously converted to a `NonNull` /// pointer using [`Box::into_non_null`]: /// ``` /// #![feature(box_vec_non_null)] /// /// let x = Box::new(5); /// let non_null = Box::into_non_null(x); /// let x = unsafe { Box::from_non_null(non_null) }; /// ``` /// Manually create a `Box` from scratch by using the global allocator: /// ``` /// #![feature(box_vec_non_null)] /// /// use std::alloc::{alloc, Layout}; /// use std::ptr::NonNull; /// /// unsafe { /// let non_null = NonNull::new(alloc(Layout::new::()).cast::()) /// .expect("allocation failed"); /// // 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(non_null); /// } /// ``` /// /// [memory layout]: self#memory-layout #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] #[inline] #[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"] pub unsafe fn from_non_null(ptr: NonNull) -> Self { unsafe { Self::from_raw(ptr.as_ptr()) } } /// Consumes the `Box`, returning a wrapped raw pointer. /// /// The pointer will be properly aligned and non-null. /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory, taking /// into account the [memory layout] used by `Box`. The easiest way to /// do this is to convert the raw pointer back into a `Box` with the /// [`Box::from_raw`] function, allowing the `Box` destructor to perform /// the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This /// is so that there is no conflict with a method on the inner type. /// /// # Examples /// Converting the raw pointer back into a `Box` with [`Box::from_raw`] /// for automatic cleanup: /// ``` /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); /// let x = unsafe { Box::from_raw(ptr) }; /// ``` /// Manual cleanup by explicitly running the destructor and deallocating /// the memory: /// ``` /// use std::alloc::{dealloc, Layout}; /// use std::ptr; /// /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); /// unsafe { /// ptr::drop_in_place(ptr); /// dealloc(ptr as *mut u8, Layout::new::()); /// } /// ``` /// Note: This is equivalent to the following: /// ``` /// let x = Box::new(String::from("Hello")); /// let ptr = Box::into_raw(x); /// unsafe { /// drop(Box::from_raw(ptr)); /// } /// ``` /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Self) -> *mut T { // Avoid `into_raw_with_allocator` as that interacts poorly with Miri's Stacked Borrows. let mut b = mem::ManuallyDrop::new(b); // We go through the built-in deref for `Box`, which is crucial for Miri to recognize this // operation for it's alias tracking. &raw mut **b } /// Consumes the `Box`, returning a wrapped `NonNull` pointer. /// /// The pointer will be properly aligned. /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory, taking /// into account the [memory layout] used by `Box`. The easiest way to /// do this is to convert the `NonNull` pointer back into a `Box` with the /// [`Box::from_non_null`] function, allowing the `Box` destructor to /// perform the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_non_null(b)` instead of `b.into_non_null()`. /// This is so that there is no conflict with a method on the inner type. /// /// # Examples /// Converting the `NonNull` pointer back into a `Box` with [`Box::from_non_null`] /// for automatic cleanup: /// ``` /// #![feature(box_vec_non_null)] /// /// let x = Box::new(String::from("Hello")); /// let non_null = Box::into_non_null(x); /// let x = unsafe { Box::from_non_null(non_null) }; /// ``` /// Manual cleanup by explicitly running the destructor and deallocating /// the memory: /// ``` /// #![feature(box_vec_non_null)] /// /// use std::alloc::{dealloc, Layout}; /// /// let x = Box::new(String::from("Hello")); /// let non_null = Box::into_non_null(x); /// unsafe { /// non_null.drop_in_place(); /// dealloc(non_null.as_ptr().cast::(), Layout::new::()); /// } /// ``` /// Note: This is equivalent to the following: /// ``` /// #![feature(box_vec_non_null)] /// /// let x = Box::new(String::from("Hello")); /// let non_null = Box::into_non_null(x); /// unsafe { /// drop(Box::from_non_null(non_null)); /// } /// ``` /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] #[inline] pub fn into_non_null(b: Self) -> NonNull { // SAFETY: `Box` is guaranteed to be non-null. unsafe { NonNull::new_unchecked(Self::into_raw(b)) } } } impl Box { /// 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::())?.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::())?.cast::(); /// // 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, 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. /// /// The pointer will be properly aligned and non-null. /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory, taking /// into account the [memory layout] used by `Box`. The easiest way to /// do this is to convert the raw pointer back into a `Box` with the /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform /// the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw_with_allocator(b)` instead of `b.into_raw_with_allocator()`. This /// is so that there is no conflict with a method on the inner type. /// /// # Examples /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`] /// for automatic cleanup: /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::System; /// /// let x = Box::new_in(String::from("Hello"), System); /// let (ptr, alloc) = Box::into_raw_with_allocator(x); /// let x = unsafe { Box::from_raw_in(ptr, alloc) }; /// ``` /// Manual cleanup by explicitly running the destructor and deallocating /// the memory: /// ``` /// #![feature(allocator_api)] /// /// use std::alloc::{Allocator, Layout, System}; /// use std::ptr::{self, NonNull}; /// /// let x = Box::new_in(String::from("Hello"), System); /// let (ptr, alloc) = Box::into_raw_with_allocator(x); /// unsafe { /// ptr::drop_in_place(ptr); /// let non_null = NonNull::new_unchecked(ptr); /// alloc.deallocate(non_null.cast(), Layout::new::()); /// } /// ``` /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what // is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we // want *no* aliasing requirements here! // In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw` // works around that. let ptr = &raw mut **b; let alloc = unsafe { ptr::read(&b.1) }; (ptr, alloc) } /// Consumes the `Box`, returning a wrapped `NonNull` pointer and the allocator. /// /// The pointer will be properly aligned. /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory, taking /// into account the [memory layout] used by `Box`. The easiest way to /// do this is to convert the `NonNull` pointer back into a `Box` with the /// [`Box::from_non_null_in`] function, allowing the `Box` destructor to /// perform the cleanup. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_non_null_with_allocator(b)` instead of /// `b.into_non_null_with_allocator()`. This is so that there is no /// conflict with a method on the inner type. /// /// # Examples /// Converting the `NonNull` pointer back into a `Box` with /// [`Box::from_non_null_in`] for automatic cleanup: /// ``` /// #![feature(allocator_api, box_vec_non_null)] /// /// use std::alloc::System; /// /// let x = Box::new_in(String::from("Hello"), System); /// let (non_null, alloc) = Box::into_non_null_with_allocator(x); /// let x = unsafe { Box::from_non_null_in(non_null, alloc) }; /// ``` /// Manual cleanup by explicitly running the destructor and deallocating /// the memory: /// ``` /// #![feature(allocator_api, box_vec_non_null)] /// /// use std::alloc::{Allocator, Layout, System}; /// /// let x = Box::new_in(String::from("Hello"), System); /// let (non_null, alloc) = Box::into_non_null_with_allocator(x); /// unsafe { /// non_null.drop_in_place(); /// alloc.deallocate(non_null.cast::(), Layout::new::()); /// } /// ``` /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] #[inline] pub fn into_non_null_with_allocator(b: Self) -> (NonNull, A) { let (ptr, alloc) = Box::into_raw_with_allocator(b); // SAFETY: `Box` is guaranteed to be non-null. unsafe { (NonNull::new_unchecked(ptr), alloc) } } #[unstable( feature = "ptr_internals", issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] #[inline] #[doc(hidden)] pub fn into_unique(b: Self) -> (Unique, A) { let (ptr, alloc) = Box::into_raw_with_allocator(b); unsafe { (Unique::from(&mut *ptr), alloc) } } /// Returns a raw mutable pointer to the `Box`'s contents. /// /// The caller must ensure that the `Box` outlives the pointer this /// function returns, or else it will end up dangling. /// /// This method guarantees that for the purpose of the aliasing model, this method /// does not materialize a reference to the underlying memory, and thus the returned pointer /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. /// Note that calling other methods that materialize references to the memory /// may still invalidate this pointer. /// See the example below for how this guarantee can be used. /// /// # Examples /// /// Due to the aliasing guarantee, the following code is legal: /// /// ```rust /// #![feature(box_as_ptr)] /// /// unsafe { /// let mut b = Box::new(0); /// let ptr1 = Box::as_mut_ptr(&mut b); /// ptr1.write(1); /// let ptr2 = Box::as_mut_ptr(&mut b); /// ptr2.write(2); /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: /// ptr1.write(3); /// } /// ``` /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] #[inline] pub fn as_mut_ptr(b: &mut Self) -> *mut T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing // any references. &raw mut **b } /// Returns a raw pointer to the `Box`'s contents. /// /// The caller must ensure that the `Box` outlives the pointer this /// function returns, or else it will end up dangling. /// /// The caller must also ensure that the memory the pointer (non-transitively) points to /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer /// derived from it. If you need to mutate the contents of the `Box`, use [`as_mut_ptr`]. /// /// This method guarantees that for the purpose of the aliasing model, this method /// does not materialize a reference to the underlying memory, and thus the returned pointer /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. /// Note that calling other methods that materialize mutable references to the memory, /// as well as writing to this memory, may still invalidate this pointer. /// See the example below for how this guarantee can be used. /// /// # Examples /// /// Due to the aliasing guarantee, the following code is legal: /// /// ```rust /// #![feature(box_as_ptr)] /// /// unsafe { /// let mut v = Box::new(0); /// let ptr1 = Box::as_ptr(&v); /// let ptr2 = Box::as_mut_ptr(&mut v); /// let _val = ptr2.read(); /// // No write to this memory has happened yet, so `ptr1` is still valid. /// let _val = ptr1.read(); /// // However, once we do a write... /// ptr2.write(1); /// // ... `ptr1` is no longer valid. /// // This would be UB: let _val = ptr1.read(); /// } /// ``` /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] #[inline] pub fn as_ptr(b: &Self) -> *const T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing // any references. &raw const **b } /// Returns a reference to the underlying allocator. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This /// is so that there is no conflict with a method on the inner type. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn allocator(b: &Self) -> &A { &b.1 } /// Consumes and leaks the `Box`, returning a mutable reference, /// `&'a mut T`. /// /// Note that the type `T` must outlive the chosen lifetime `'a`. If the type /// has only static references, or none at all, then this may be chosen to be /// `'static`. /// /// This function is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory /// leak. If this is not acceptable, the reference should first be wrapped /// with the [`Box::from_raw`] function producing a `Box`. This `Box` can /// then be dropped which will properly destroy `T` and release the /// allocated memory. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::leak(b)` instead of `b.leak()`. This /// is so that there is no conflict with a method on the inner type. /// /// # Examples /// /// Simple usage: /// /// ``` /// let x = Box::new(41); /// let static_ref: &'static mut usize = Box::leak(x); /// *static_ref += 1; /// assert_eq!(*static_ref, 42); /// # // FIXME(https://github.com/rust-lang/miri/issues/3670): /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak. /// # drop(unsafe { Box::from_raw(static_ref) }); /// ``` /// /// Unsized data: /// /// ``` /// let x = vec![1, 2, 3].into_boxed_slice(); /// let static_ref = Box::leak(x); /// static_ref[0] = 4; /// assert_eq!(*static_ref, [4, 2, 3]); /// # // FIXME(https://github.com/rust-lang/miri/issues/3670): /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak. /// # drop(unsafe { Box::from_raw(static_ref) }); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] #[inline] pub fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { let (ptr, alloc) = Box::into_raw_with_allocator(b); mem::forget(alloc); unsafe { &mut *ptr } } /// Converts a `Box` into a `Pin>`. If `T` does not implement [`Unpin`], then /// `*boxed` will be pinned in memory and unable to be moved. /// /// This conversion does not allocate on the heap and happens in place. /// /// This is also available via [`From`]. /// /// Constructing and pinning a `Box` with Box::into_pin([Box::new]\(x)) /// can also be written more concisely using [Box::pin]\(x). /// This `into_pin` method is useful if you already have a `Box`, or you are /// constructing a (pinned) `Box` in a different way than with [`Box::new`]. /// /// # Notes /// /// It's not recommended that crates add an impl like `From> for Pin`, /// as it'll introduce an ambiguity when calling `Pin::from`. /// A demonstration of such a poor impl is shown below. /// /// ```compile_fail /// # use std::pin::Pin; /// struct Foo; // A type defined in this crate. /// impl From> for Pin { /// fn from(_: Box<()>) -> Pin { /// Pin::new(Foo) /// } /// } /// /// let foo = Box::new(()); /// let bar = Pin::from(foo); /// ``` #[stable(feature = "box_into_pin", since = "1.63.0")] pub fn into_pin(boxed: Self) -> Pin where A: 'static, { // It's not possible to move or replace the insides of a `Pin>` // when `T: !Unpin`, so it's safe to pin it directly without any // additional requirements. unsafe { Pin::new_unchecked(boxed) } } } #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box { #[inline] fn drop(&mut self) { // 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()); if layout.size() != 0 { self.1.deallocate(From::from(ptr.cast()), layout); } } } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Box { /// Creates a `Box`, with the `Default` value for `T`. #[inline] fn default() -> Self { let mut x: Box> = Box::new_uninit(); unsafe { // SAFETY: `x` is valid for writing and has the same layout as `T`. // If `T::default()` panics, dropping `x` will just deallocate the Box as `MaybeUninit` // does not have a destructor. // // We use `ptr::write` as `MaybeUninit::write` creates // extra stack copies of `T` in debug mode. // // See https://github.com/rust-lang/rust/issues/136043 for more context. ptr::write(&raw mut *x as *mut T, T::default()); // SAFETY: `x` was just initialized above. x.assume_init() } } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for Box<[T]> { /// Creates an empty `[T]` inside a `Box`. #[inline] fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); Box(ptr, Global) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { #[inline] fn default() -> Self { // SAFETY: This is the same as `Unique::cast` but with an unsized `U = str`. let ptr: Unique = unsafe { let bytes: Unique<[u8]> = Unique::<[u8; 0]>::dangling(); Unique::new_unchecked(bytes.as_ptr() as *mut str) }; Box(ptr, Global) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "pin_default_impls", since = "1.91.0")] impl Default for Pin> where T: ?Sized, Box: Default, { #[inline] fn default() -> Self { Box::into_pin(Box::::default()) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Box { /// Returns a new box with a `clone()` of this box's contents. /// /// # Examples /// /// ``` /// let x = Box::new(5); /// let y = x.clone(); /// /// // The value is the same /// assert_eq!(x, y); /// /// // But they are unique objects /// assert_ne!(&*x as *const i32, &*y as *const i32); /// ``` #[inline] fn clone(&self) -> Self { // Pre-allocate memory to allow writing the cloned value directly. let mut boxed = Self::new_uninit_in(self.1.clone()); unsafe { (**self).clone_to_uninit(boxed.as_mut_ptr().cast()); boxed.assume_init() } } /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples /// /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); /// let yp: *const i32 = &*y; /// /// y.clone_from(&x); /// /// // The value is the same /// assert_eq!(x, y); /// /// // And no allocation occurred /// assert_eq!(yp, &*y); /// ``` #[inline] fn clone_from(&mut self, source: &Self) { (**self).clone_from(&(**source)); } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box<[T], A> { fn clone(&self) -> Self { let alloc = Box::allocator(self).clone(); self.to_vec_in(alloc).into_boxed_slice() } /// Copies `source`'s contents into `self` without creating a new allocation, /// so long as the two are of the same length. /// /// # Examples /// /// ``` /// let x = Box::new([5, 6, 7]); /// let mut y = Box::new([8, 9, 10]); /// let yp: *const [i32] = &*y; /// /// y.clone_from(&x); /// /// // The value is the same /// assert_eq!(x, y); /// /// // And no allocation occurred /// assert_eq!(yp, &*y); /// ``` fn clone_from(&mut self, source: &Self) { if self.len() == source.len() { self.clone_from_slice(&source); } else { *self = source.clone(); } } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box { fn clone(&self) -> Self { // this makes a copy of the data let buf: Box<[u8]> = self.as_bytes().into(); unsafe { from_boxed_utf8_unchecked(buf) } } } #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for Box { #[inline] fn eq(&self, other: &Self) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &Self) -> bool { PartialEq::ne(&**self, &**other) } } #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Box { #[inline] fn partial_cmp(&self, other: &Self) -> Option { PartialOrd::partial_cmp(&**self, &**other) } #[inline] fn lt(&self, other: &Self) -> bool { PartialOrd::lt(&**self, &**other) } #[inline] fn le(&self, other: &Self) -> bool { PartialOrd::le(&**self, &**other) } #[inline] fn ge(&self, other: &Self) -> bool { PartialOrd::ge(&**self, &**other) } #[inline] fn gt(&self, other: &Self) -> bool { PartialOrd::gt(&**self, &**other) } } #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Box { #[inline] fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(&**self, &**other) } } #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Box {} #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Box { fn hash(&self, state: &mut H) { (**self).hash(state); } } #[stable(feature = "indirect_hasher_impl", since = "1.22.0")] impl Hasher for Box { fn finish(&self) -> u64 { (**self).finish() } fn write(&mut self, bytes: &[u8]) { (**self).write(bytes) } fn write_u8(&mut self, i: u8) { (**self).write_u8(i) } fn write_u16(&mut self, i: u16) { (**self).write_u16(i) } fn write_u32(&mut self, i: u32) { (**self).write_u32(i) } fn write_u64(&mut self, i: u64) { (**self).write_u64(i) } fn write_u128(&mut self, i: u128) { (**self).write_u128(i) } fn write_usize(&mut self, i: usize) { (**self).write_usize(i) } fn write_i8(&mut self, i: i8) { (**self).write_i8(i) } fn write_i16(&mut self, i: i16) { (**self).write_i16(i) } fn write_i32(&mut self, i: i32) { (**self).write_i32(i) } fn write_i64(&mut self, i: i64) { (**self).write_i64(i) } fn write_i128(&mut self, i: i128) { (**self).write_i128(i) } fn write_isize(&mut self, i: isize) { (**self).write_isize(i) } fn write_length_prefix(&mut self, len: usize) { (**self).write_length_prefix(len) } fn write_str(&mut self, s: &str) { (**self).write_str(s) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Box { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Box { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Pointer for Box { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // It's not possible to extract the inner Uniq directly from the Box, // instead we cast it to a *const which aliases the Unique let ptr: *const T = &**self; fmt::Pointer::fmt(&ptr, f) } } #[stable(feature = "rust1", since = "1.0.0")] impl Deref for Box { type Target = T; fn deref(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] impl DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } } #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Box {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Box {} #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> FnOnce for Box { type Output = >::Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output { >::call_once(*self, args) } } #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> FnMut for Box { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { >::call_mut(self, args) } } #[stable(feature = "boxed_closure_impls", since = "1.35.0")] impl + ?Sized, A: Allocator> Fn for Box { extern "rust-call" fn call(&self, args: Args) -> Self::Output { >::call(self, args) } } #[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFnOnce for Box { type Output = F::Output; type CallOnceFuture = F::CallOnceFuture; extern "rust-call" fn async_call_once(self, args: Args) -> Self::CallOnceFuture { F::async_call_once(*self, args) } } #[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFnMut for Box { type CallRefFuture<'a> = F::CallRefFuture<'a> where Self: 'a; extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_> { F::async_call_mut(self, args) } } #[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFn for Box { extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> { F::async_call(self, args) } } #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for Box {} // It is quite crucial that we only allow the `Global` allocator here. // Handling arbitrary custom allocators (which can affect the `Box` layout heavily!) // would need a lot of codegen and interpreter adjustments. #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U: ?Sized> DispatchFromDyn> for Box {} #[stable(feature = "box_borrow", since = "1.1.0")] impl Borrow for Box { fn borrow(&self) -> &T { &**self } } #[stable(feature = "box_borrow", since = "1.1.0")] impl BorrowMut for Box { fn borrow_mut(&mut self) -> &mut T { &mut **self } } #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] impl AsRef for Box { fn as_ref(&self) -> &T { &**self } } #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] impl AsMut for Box { fn as_mut(&mut self) -> &mut T { &mut **self } } /* Nota bene * * We could have chosen not to add this impl, and instead have written a * function of Pin> to Pin. Such a function would not be sound, * because Box implements Unpin even when T does not, as a result of * this impl. * * We chose this API instead of the alternative for a few reasons: * - Logically, it is helpful to understand pinning in regard to the * memory region being pointed to. For this reason none of the * standard library pointer types support projecting through a pin * (Box is the only pointer type in std for which this would be * safe.) * - It is in practice very useful to have Box be unconditionally * Unpin because of trait objects, for which the structural auto * trait functionality does not apply (e.g., Box would * otherwise not be Unpin). * * Another type with the same semantics as Box but only a conditional * implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and * could have a method to project a Pin from it. */ #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Box {} #[unstable(feature = "coroutine_trait", issue = "43122")] impl + Unpin, R, A: Allocator> Coroutine for Box { type Yield = G::Yield; type Return = G::Return; fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { G::resume(Pin::new(&mut *self), arg) } } #[unstable(feature = "coroutine_trait", issue = "43122")] impl, R, A: Allocator> Coroutine for Pin> where A: 'static, { type Yield = G::Yield; type Return = G::Return; fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState { G::resume((*self).as_mut(), arg) } } #[stable(feature = "futures_api", since = "1.36.0")] impl Future for Box { type Output = F::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { F::poll(Pin::new(&mut *self), cx) } } #[stable(feature = "box_error", since = "1.8.0")] impl Error for Box { #[allow(deprecated)] fn cause(&self) -> Option<&dyn Error> { Error::cause(&**self) } fn source(&self) -> Option<&(dyn Error + 'static)> { Error::source(&**self) } fn provide<'b>(&'b self, request: &mut error::Request<'b>) { Error::provide(&**self, request); } }