// SPDX-License-Identifier: Apache-2.0 OR MIT //! The `Box<T>` type for heap allocation.//!//! [`Box<T>`], 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<u8> = Box::new(val);//! ```//!//! Move a value from a [`Box`] back to the stack by [dereferencing]://!//! ```//! let boxed: Box<u8> = Box::new(5);//! let val: u8 = *boxed;//! ```//!//! Creating a recursive data structure://!//! ```//! #[derive(Debug)]//! enum List<T> {//! Cons(T, Box<List<T>>),//! Nil,//! }//!//! let list: List<i32> = 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<T> {//! Cons(T, List<T>),//! # }//! ```//!//! 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<T>`], 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. 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::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the//! [`Global`] allocator with [`Layout::for_value(&*value)`].//!//! For zero-sized values, the `Box` pointer still has to be [valid] for reads//! and writes and sufficiently aligned. In particular, casting any aligned//! non-zero integer literal to a raw pointer produces a valid pointer, but a//! pointer pointing into previously allocated memory that since got freed is//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot//! be used is to use [`ptr::NonNull::dangling`].//!//! So long as `T: Sized`, a `Box<T>` 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<T>` 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<Foo>`, which captures//! the ownership constraints. Note also that the nullable argument to//! `foo_delete` is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>`//! cannot be null.//!//! ```//! #[repr(C)]//! pub struct Foo;//!//! #[no_mangle]//! pub extern "C" fn foo_new() -> Box<Foo> {//! Box::new(Foo)//! }//!//! #[no_mangle]//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}//! ```//!//! Even though `Box<T>` 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<T>`//! and expect things to work. `Box<T>` values will always be fully aligned,//! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to//! free the value with the global allocator. In general, the best practice//! is to only use `Box<T>` for pointers that originated from the global//! allocator.//!//! **Important.** At least at present, you should avoid using//! `Box<T>` 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<T>` 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<T>` are the same as for `&mut T`. `Box<T>`//! 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].//!//!//! [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::<T>::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::any::Any;use core::async_iter::AsyncIterator;use core::borrow;use core::cmp::Ordering;use core::convert::{From, TryFrom};use core::error::Error;use core::fmt;use core::future::Future;use core::hash::{Hash, Hasher};#[cfg(not(no_global_oom_handling))]use core::iter::FromIterator;use core::iter::{FusedIterator, Iterator};use core::marker::Tuple;use core::marker::{Destruct, Unpin, Unsize};use core::mem;use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,};use core::pin::Pin;use core::ptr::{self, Unique};use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))]use crate::alloc::{handle_alloc_error, WriteCloneIntoRaw};use crate::alloc::{AllocError, Allocator, Global, Layout};#[cfg(not(no_global_oom_handling))]use crate::borrow::Cow;use crate::raw_vec::RawVec;#[cfg(not(no_global_oom_handling))]use crate::str::from_boxed_utf8_unchecked;#[cfg(not(no_global_oom_handling))]use crate::string::String;#[cfg(not(no_global_oom_handling))]use crate::vec::Vec; #[cfg(not(no_thin))]#[unstable(feature = "thin_box", issue = "92791")]pub use thin::ThinBox; #[cfg(not(no_thin))]mod thin; /// 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")]// The declaration of the `Box` struct must be kept in sync with the// `alloc::alloc::box_free` function or ICEs will happen. See the comment// on `box_free` for more details.pub struct Box< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,>(Unique<T>, A); impl<T> Box<T> { /// 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(all(not(no_global_oom_handling)))] #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub fn new(x: T) -> Self { #[rustc_box] Box::new(x) } /// Constructs a new box with uninitialized contents. /// /// # Examples /// /// ``` /// #![feature(new_uninit)] /// /// let mut five = Box::<u32>::new_uninit(); /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5) /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] #[inline] pub fn new_uninit() -> Box<mem::MaybeUninit<T>> { 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_uninit)] /// /// let zero = Box::<u32>::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_uninit", issue = "63291")] #[must_use] pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> { Self::new_zeroed_in(Global) } /// Constructs a new `Pin<Box<T>>`. 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 <code>[Box::into_pin]\([Box::new]\(x))</code>. Consider using /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, 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<T>> { (#[rustc_box] 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, AllocError> { 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, new_uninit)] /// /// let mut five = Box::<u32>::try_new_uninit()?; /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// 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<Box<mem::MaybeUninit<T>>, 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, new_uninit)] /// /// let zero = Box::<u32>::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<Box<mem::MaybeUninit<T>>, AllocError> { Box::try_new_zeroed_in(Global) }} impl<T, A: Allocator> Box<T, A> { /// 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")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline] pub const fn new_in(x: T, alloc: A) -> Self where A: ~const Allocator + ~const Destruct, { let mut boxed = Self::new_uninit_in(alloc); unsafe { boxed.as_mut_ptr().write(x); 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")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> where T: ~const Destruct, A: ~const Allocator + ~const Destruct, { let mut boxed = Self::try_new_uninit_in(alloc)?; unsafe { boxed.as_mut_ptr().write(x); Ok(boxed.assume_init()) } } /// Constructs a new box with uninitialized contents in the provided allocator. /// /// # Examples /// /// ``` /// #![feature(allocator_api, new_uninit)] /// /// use std::alloc::System; /// /// let mut five = Box::<u32, _>::new_uninit_in(System); /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> where A: ~const Allocator + ~const Destruct, { let layout = Layout::new::<mem::MaybeUninit<T>>(); // 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, new_uninit)] /// /// use std::alloc::System; /// /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?; /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> where A: ~const Allocator + ~const Destruct, { let layout = Layout::new::<mem::MaybeUninit<T>>(); let ptr = alloc.allocate(layout)?.cast(); unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } /// Constructs a new `Box` with uninitialized contents, with the memoryLines 1–500 of 2432. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT //! The `Box<T>` type for heap allocation. //! //! [`Box<T>`], 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<u8> = Box::new(val); //! ``` //! //! Move a value from a [`Box`] back to the stack by [dereferencing]: //! //! ``` //! let boxed: Box<u8> = Box::new(5); //! let val: u8 = *boxed; //! ``` //! //! Creating a recursive data structure: //! //! ``` //! #[derive(Debug)] //! enum List<T> { //! Cons(T, Box<List<T>>), //! Nil, //! } //! //! let list: List<i32> = 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<T> { //! Cons(T, List<T>), //! # } //! ``` //! //! 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<T>`], 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. 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::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut //! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the //! [`Global`] allocator with [`Layout::for_value(&*value)`]. //! //! For zero-sized values, the `Box` pointer still has to be [valid] for reads //! and writes and sufficiently aligned. In particular, casting any aligned //! non-zero integer literal to a raw pointer produces a valid pointer, but a //! pointer pointing into previously allocated memory that since got freed is //! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot //! be used is to use [`ptr::NonNull::dangling`]. //! //! So long as `T: Sized`, a `Box<T>` 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<T>` 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<Foo>`, which captures //! the ownership constraints. Note also that the nullable argument to //! `foo_delete` is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>` //! cannot be null. //! //! ``` //! #[repr(C)] //! pub struct Foo; //! //! #[no_mangle] //! pub extern "C" fn foo_new() -> Box<Foo> { //! Box::new(Foo) //! } //! //! #[no_mangle] //! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {} //! ``` //! //! Even though `Box<T>` 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<T>` //! and expect things to work. `Box<T>` values will always be fully aligned, //! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to //! free the value with the global allocator. In general, the best practice //! is to only use `Box<T>` for pointers that originated from the global //! allocator. //! //! **Important.** At least at present, you should avoid using //! `Box<T>` 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<T>` 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<T>` are the same as for `&mut T`. `Box<T>` //! 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]. //! //! //! [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::<T>::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::any::Any; use core::async_iter::AsyncIterator; use core::borrow; use core::cmp::Ordering; use core::convert::{From, TryFrom}; use core::error::Error; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter::FromIterator; use core::iter::{FusedIterator, Iterator}; use core::marker::Tuple; use core::marker::{Destruct, Unpin, Unsize}; use core::mem; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, }; use core::pin::Pin; use core::ptr::{self, Unique}; use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))] use crate::alloc::{handle_alloc_error, WriteCloneIntoRaw}; use crate::alloc::{AllocError, Allocator, Global, Layout}; #[cfg(not(no_global_oom_handling))] use crate::borrow::Cow; use crate::raw_vec::RawVec; #[cfg(not(no_global_oom_handling))] use crate::str::from_boxed_utf8_unchecked; #[cfg(not(no_global_oom_handling))] use crate::string::String; #[cfg(not(no_global_oom_handling))] use crate::vec::Vec; #[cfg(not(no_thin))] #[unstable(feature = "thin_box", issue = "92791")] pub use thin::ThinBox; #[cfg(not(no_thin))] mod thin; /// 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")] // The declaration of the `Box` struct must be kept in sync with the // `alloc::alloc::box_free` function or ICEs will happen. See the comment // on `box_free` for more details. pub struct Box< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, >(Unique<T>, A); impl<T> Box<T> { /// 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(all(not(no_global_oom_handling)))] #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub fn new(x: T) -> Self { #[rustc_box] Box::new(x) } /// Constructs a new box with uninitialized contents. /// /// # Examples /// /// ``` /// #![feature(new_uninit)] /// /// let mut five = Box::<u32>::new_uninit(); /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5) /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] #[inline] pub fn new_uninit() -> Box<mem::MaybeUninit<T>> { 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_uninit)] /// /// let zero = Box::<u32>::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_uninit", issue = "63291")] #[must_use] pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> { Self::new_zeroed_in(Global) } /// Constructs a new `Pin<Box<T>>`. 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 <code>[Box::into_pin]\([Box::new]\(x))</code>. Consider using /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, 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<T>> { (#[rustc_box] 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, AllocError> { 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, new_uninit)] /// /// let mut five = Box::<u32>::try_new_uninit()?; /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// 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<Box<mem::MaybeUninit<T>>, 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, new_uninit)] /// /// let zero = Box::<u32>::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<Box<mem::MaybeUninit<T>>, AllocError> { Box::try_new_zeroed_in(Global) } } impl<T, A: Allocator> Box<T, A> { /// 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")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline] pub const fn new_in(x: T, alloc: A) -> Self where A: ~const Allocator + ~const Destruct, { let mut boxed = Self::new_uninit_in(alloc); unsafe { boxed.as_mut_ptr().write(x); 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")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> where T: ~const Destruct, A: ~const Allocator + ~const Destruct, { let mut boxed = Self::try_new_uninit_in(alloc)?; unsafe { boxed.as_mut_ptr().write(x); Ok(boxed.assume_init()) } } /// Constructs a new box with uninitialized contents in the provided allocator. /// /// # Examples /// /// ``` /// #![feature(allocator_api, new_uninit)] /// /// use std::alloc::System; /// /// let mut five = Box::<u32, _>::new_uninit_in(System); /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> where A: ~const Allocator + ~const Destruct, { let layout = Layout::new::<mem::MaybeUninit<T>>(); // 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, new_uninit)] /// /// use std::alloc::System; /// /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?; /// /// let five = unsafe { /// // Deferred initialization: /// five.as_mut_ptr().write(5); /// /// five.assume_init() /// }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] #[rustc_const_unstable(feature = "const_box", issue = "92521")] pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> where A: ~const Allocator + ~const Destruct, { let layout = Layout::new::<mem::MaybeUninit<T>>(); let ptr = alloc.allocate(layout)?.cast(); unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } /// Constructs a new `Box` with uninitialized contents, with the memory