Rollup merge of #91884 - woppopo:const_box, r=oli-obk
Constify `Box<T, A>` methods
Tracking issue: none yet
Most of the methods bounded on `~const`. `intrinsics::const_eval_select` is used for handling an allocation error.
<details><summary>Constified API</summary>
```rust
impl<T, A: Allocator> Box<T, A> {
pub const fn new_in(x: T, alloc: A) -> Self
where
A: ~const Allocator + ~const Drop;
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
where
T: ~const Drop,
A: ~const Allocator + ~const Drop;
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
where
A: ~const Allocator + ~const Drop;
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
where
A: ~const Allocator + ~const Drop;
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
where
A: ~const Allocator + ~const Drop;
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
where
A: ~const Allocator + ~const Drop;
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
where
A: 'static,
A: 'static + ~const Allocator + ~const Drop,
pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A>;
pub const fn into_inner(boxed: Self) -> T
where
Self: ~const Drop,
}
impl<T, A: Allocator> Box<MaybeUninit<T>, A> {
pub const unsafe fn assume_init(self) -> Box<T, A>;
pub const fn write(mut boxed: Self, value: T) -> Box<T, A>;
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self;
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A);
pub const fn into_unique(b: Self) -> (Unique<T>, A);
pub const fn allocator(b: &Self) -> &A;
pub const fn leak<'a>(b: Self) -> &'a mut T
where
A: 'a;
pub const fn into_pin(boxed: Self) -> Pin<Self>
where
A: 'static;
}
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> const Drop for Box<T, A>;
impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
where
A: 'static;
impl<T: ?Sized, A: Allocator> const Deref for Box<T, A>;
impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A>;
impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static;
```
</details>
<details><summary>Example</summary>
```rust
pub struct ConstAllocator;
unsafe impl const Allocator for ConstAllocator {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
unsafe {
let ptr = core::intrinsics::const_allocate(layout.size(), layout.align());
Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8]))
}
}
unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {
/* do nothing */
}
fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
self.allocate(layout)
}
unsafe fn grow(
&self,
_ptr: NonNull<u8>,
_old_layout: Layout,
_new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
unimplemented!()
}
unsafe fn grow_zeroed(
&self,
_ptr: NonNull<u8>,
_old_layout: Layout,
_new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
unimplemented!()
}
unsafe fn shrink(
&self,
_ptr: NonNull<u8>,
_old_layout: Layout,
_new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
unimplemented!()
}
fn by_ref(&self) -> &Self
where
Self: Sized,
{
self
}
}
#[test]
fn const_box() {
const VALUE: u32 = {
let mut boxed = Box::new_in(1u32, ConstAllocator);
assert!(*boxed == 1);
*boxed = 42;
assert!(*boxed == 42);
*boxed
};
assert!(VALUE == 42);
}
```
</details>