rune_alloc/
boxed.rs

1//! The `Box<T>` type for heap allocation.
2//!
3//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
4//! heap allocation in Rust. Boxes provide ownership for this allocation, and
5//! drop their contents when they go out of scope. Boxes also ensure that they
6//! never allocate more than `isize::MAX` bytes.
7//!
8//! # Examples
9//!
10//! Move a value from the stack to the heap by creating a [`Box`]:
11//!
12//! ```
13//! use rune::alloc::Box;
14//!
15//! let val: u8 = 5;
16//! let boxed: Box<u8> = Box::try_new(val)?;
17//! # Ok::<_, rune::alloc::Error>(())
18//! ```
19//!
20//! Move a value from a [`Box`] back to the stack using [Box::into_inner]:
21//!
22//! ```
23//! use rune::alloc::Box;
24//!
25//! let boxed: Box<u8> = Box::try_new(5)?;
26//! let val: u8 = Box::into_inner(boxed);
27//! # Ok::<_, rune::alloc::Error>(())
28//! ```
29//!
30//! Creating a recursive data structure:
31//!
32//! ```
33//! use rune::alloc::Box;
34//!
35//! #[derive(Debug)]
36//! enum List<T> {
37//!     Cons(T, Box<List<T>>),
38//!     Nil,
39//! }
40//!
41//! let list: List<i32> = List::Cons(1, Box::try_new(List::Cons(2, Box::try_new(List::Nil)?))?);
42//! println!("{list:?}");
43//! # Ok::<_, rune::alloc::Error>(())
44//! ```
45//!
46//! This will print `Cons(1, Cons(2, Nil))`.
47//!
48//! Recursive structures must be boxed, because if the definition of `Cons`
49//! looked like this:
50//!
51//! ```compile_fail,E0072
52//! # enum List<T> {
53//! Cons(T, List<T>),
54//! # }
55//! ```
56//!
57//! It wouldn't work. This is because the size of a `List` depends on how many
58//! elements are in the list, and so we don't know how much memory to allocate
59//! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know
60//! how big `Cons` needs to be.
61//!
62//! # Memory layout
63//!
64//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
65//! its allocation. It is valid to convert both ways between a [`Box`] and a raw
66//! pointer allocated with the [`Global`] allocator, given that the [`Layout`]
67//! used with the allocator is correct for the type. More precisely, a `value:
68//! *mut T` that has been allocated with the [`Global`] allocator with
69//! `Layout::for_value(&*value)` may be converted into a box using
70//! [`Box::<T>::from_raw_in(value)`]. Conversely, the memory backing a `value:
71//! *mut T` obtained from [`Box::<T>::into_raw_with_allocator`] may be
72//! deallocated using the [`Global`] allocator with
73//! [`Layout::for_value(&*value)`].
74//!
75//! For zero-sized values, the `Box` pointer still has to be [valid] for reads
76//! and writes and sufficiently aligned. In particular, casting any aligned
77//! non-zero integer literal to a raw pointer produces a valid pointer, but a
78//! pointer pointing into previously allocated memory that since got freed is
79//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot
80//! be used is to use [`ptr::NonNull::dangling`].
81//!
82//! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented as a
83//! single pointer and is also ABI-compatible with C pointers (i.e. the C type
84//! `T*`). This means that if you have extern "C" Rust functions that will be
85//! called from C, you can define those Rust functions using `Box<T>` types, and
86//! use `T*` as corresponding type on the C side. As an example, consider this C
87//! header which declares functions that create and destroy some kind of `Foo`
88//! value:
89//!
90//! ```c
91//! /* C header */
92//!
93//! /* Returns ownership to the caller */
94//! struct Foo* foo_new(void);
95//!
96//! /* Takes ownership from the caller; no-op when invoked with null */
97//! void foo_delete(struct Foo*);
98//! ```
99//!
100//! These two functions might be implemented in Rust as follows. Here, the
101//! `struct Foo*` type from C is translated to `Box<Foo>`, which captures the
102//! ownership constraints. Note also that the nullable argument to `foo_delete`
103//! is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>` cannot be
104//! null.
105//!
106//! ```
107//! use rune::alloc::Box;
108//! use rune::alloc::alloc::AllocError;
109//!
110//! #[repr(C)]
111//! pub struct Foo;
112//!
113//! #[no_mangle]
114//! pub extern "C" fn foo_new() -> Result<Box<Foo>, AllocError> {
115//!     Box::try_new(Foo)
116//! }
117//!
118//! #[no_mangle]
119//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
120//! ```
121//!
122//! Even though `Box<T>` has the same representation and C ABI as a C pointer,
123//! this does not mean that you can convert an arbitrary `T*` into a `Box<T>`
124//! and expect things to work. `Box<T>` values will always be fully aligned,
125//! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to
126//! free the value with the global allocator. In general, the best practice is
127//! to only use `Box<T>` for pointers that originated from the global allocator.
128//!
129//! **Important.** At least at present, you should avoid using `Box<T>` types
130//! for functions that are defined in C but invoked from Rust. In those cases,
131//! you should directly mirror the C types as closely as possible. Using types
132//! like `Box<T>` where the C definition is just using `T*` can lead to
133//! undefined behavior, as described in
134//! [rust-lang/unsafe-code-guidelines#198][ucg#198].
135//!
136//! # Considerations for unsafe code
137//!
138//! **Warning: This section is not normative and is subject to change, possibly
139//! being relaxed in the future! It is a simplified summary of the rules
140//! currently implemented in the compiler.**
141//!
142//! The aliasing rules for `Box<T>` are the same as for `&mut T`. `Box<T>`
143//! asserts uniqueness over its content. Using raw pointers derived from a box
144//! after that box has been mutated through, moved or borrowed as `&mut T` is
145//! not allowed. For more guidance on working with box from unsafe code, see
146//! [rust-lang/unsafe-code-guidelines#326][ucg#326].
147//!
148//!
149//! [ucg#198]: https://github.com/rust-lang/unsafe-code-guidelines/issues/198
150//! [ucg#326]: https://github.com/rust-lang/unsafe-code-guidelines/issues/326
151//! [dereferencing]: core::ops::Deref
152//! [`Box::<T>::from_raw_in(value)`]: Box::from_raw_in
153//! [`Global`]: crate::alloc::Global
154//! [`Layout`]: core::alloc::Layout
155//! [`Layout::for_value(&*value)`]: core::alloc::Layout::for_value
156//! [valid]: core::ptr#safety
157
158use core::alloc::Layout;
159use core::borrow::{Borrow, BorrowMut};
160use core::cmp::Ordering;
161use core::fmt;
162use core::hash::{Hash, Hasher};
163use core::mem;
164use core::ops::{Deref, DerefMut};
165use core::pin::Pin;
166
167use crate::alloc::{AllocError, Allocator, Global};
168use crate::clone::TryClone;
169use crate::error::Error;
170use crate::iter::TryFromIteratorIn;
171use crate::path::Path;
172use crate::ptr::{self, Unique};
173use crate::raw_vec::RawVec;
174use crate::vec::Vec;
175
176#[test]
177fn ensure_niche_size() {
178    assert_eq!(
179        core::mem::size_of::<Option<Box<u32>>>(),
180        core::mem::size_of::<Box<u32>>()
181    );
182}
183
184/// A pointer type that uniquely owns a heap allocation of type `T`.
185pub struct Box<T, A = Global>
186where
187    T: ?Sized,
188    A: Allocator,
189{
190    ptr: Unique<T>,
191    alloc: A,
192}
193
194impl<T> Box<T, Global> {
195    /// Allocates memory on the heap and then places `x` into it.
196    ///
197    /// This doesn't actually allocate if `T` is zero-sized.
198    ///
199    /// # Examples
200    ///
201    /// ```
202    /// use rune::alloc::Box;
203    ///
204    /// let five = Box::try_new(5)?;
205    /// # Ok::<_, rune::alloc::Error>(())
206    /// ```
207    pub fn try_new(value: T) -> Result<Self, AllocError> {
208        Self::try_new_in(value, Global)
209    }
210
211    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement [`Unpin`],
212    /// then `x` will be pinned in memory and unable to be moved.
213    ///
214    /// Constructing and pinning of the `Box` can also be done in two steps:
215    /// `Box::try?pin(x)` does the same as
216    /// <code>[Box::into_pin]\([Box::try?new]\(x))</code>. Consider using
217    /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, or if you
218    /// want to construct a (pinned) `Box` in a different way than with
219    /// [`Box::try_new`].
220    #[inline(always)]
221    pub fn try_pin(x: T) -> Result<Pin<Box<T>>, AllocError> {
222        Ok(Box::try_new(x)?.into())
223    }
224}
225
226impl<T: ?Sized> Box<T> {
227    /// Convert from a std `Box`.
228    ///
229    /// This causes the underlying allocation to be accounted for by the
230    /// [`Global`] allocator.
231    ///
232    /// A caveat of this method is that the allocation is already in use, but
233    /// this might still be necessary because we want access to certain methods
234    /// in std `Box` such as the ability to coerce to unsized values.
235    ///
236    /// # Examples
237    ///
238    /// ```
239    /// use rune::alloc::{Box, Vec};
240    /// use rune::alloc::limit;
241    /// use std::boxed::Box as StdBox;
242    ///
243    /// assert_eq!(limit::get(), usize::MAX);
244    ///
245    /// let b: StdBox<dyn Iterator<Item = u32>> = StdBox::new(1..3);
246    /// let mut b = Box::from_std(b)?;
247    /// assert_eq!(b.next(), Some(1));
248    /// assert_eq!(b.next(), Some(2));
249    /// assert_eq!(b.next(), None);
250    ///
251    /// assert!(limit::get() < usize::MAX);
252    /// drop(b);
253    ///
254    /// assert_eq!(limit::get(), usize::MAX);
255    /// # Ok::<_, rune::alloc::Error>(())
256    /// ```
257    #[cfg(feature = "alloc")]
258    pub fn from_std(b: rust_alloc::boxed::Box<T>) -> Result<Self, Error> {
259        // SAFETY: We've ensured that standard allocations only happen in an
260        // allocator which is compatible with our `Global`.
261        unsafe {
262            // NB: Layout::for_value will return the size of the pointed to
263            // value by the box, which for unsized types is the size of the
264            // metadata. For sized types the value inside of the box.
265            Global.take(Layout::for_value(b.as_ref()))?;
266            let raw = rust_alloc::boxed::Box::into_raw(b);
267            Ok(Box::from_raw_in(raw, Global))
268        }
269    }
270}
271
272impl<T, A> Box<T, A>
273where
274    A: Allocator,
275{
276    /// Allocates memory in the given allocator then places `x` into it,
277    /// returning an error if the allocation fails
278    ///
279    /// This doesn't actually allocate if `T` is zero-sized.
280    ///
281    /// # Examples
282    ///
283    /// ```
284    /// use rune::alloc::Box;
285    /// use rune::alloc::alloc::Global;
286    ///
287    /// let five = Box::try_new_in(5, Global)?;
288    /// # Ok::<_, rune::alloc::Error>(())
289    /// ```
290    #[inline]
291    pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
292        let mut boxed = Self::try_new_uninit_in(alloc)?;
293
294        unsafe {
295            boxed.as_mut_ptr().write(x);
296            Ok(boxed.assume_init())
297        }
298    }
299
300    /// Constructs a new box with uninitialized contents in the provided
301    /// allocator, returning an error if the allocation fails
302    ///
303    /// # Examples
304    ///
305    /// ```
306    /// use rune::alloc::Box;
307    /// use rune::alloc::alloc::Global;
308    ///
309    /// let mut five = Box::<u32>::try_new_uninit_in(Global)?;
310    ///
311    /// let five: Box<u32> = unsafe {
312    ///     // Deferred initialization:
313    ///     five.as_mut_ptr().write(5);
314    ///
315    ///     five.assume_init()
316    /// };
317    ///
318    /// assert_eq!(*five, 5);
319    /// # Ok::<_, rune::alloc::Error>(())
320    /// ```
321    pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
322        let layout = Layout::new::<mem::MaybeUninit<T>>();
323        let ptr = alloc.allocate(layout)?.cast();
324        unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
325    }
326
327    /// Consumes the `Box`, returning the wrapped value.
328    #[inline]
329    pub fn into_inner(boxed: Self) -> T {
330        let this = mem::ManuallyDrop::new(boxed);
331        let value = unsafe { ptr::read(this.ptr.as_ptr()) };
332
333        // Free memory associated with the box.
334        //
335        // SAFETY: We own the box, so we know we can safely deallocate it.
336        unsafe {
337            let layout = for_value_raw(this.ptr.as_ptr());
338
339            if layout.size() != 0 {
340                this.alloc.deallocate(From::from(this.ptr.cast()), layout);
341            }
342        }
343
344        value
345    }
346}
347
348impl<T, A> Box<T, A>
349where
350    T: ?Sized,
351    A: Allocator,
352{
353    /// Consumes and leaks the `Box`, returning a mutable reference, `&'a mut
354    /// T`. Note that the type `T` must outlive the chosen lifetime `'a`. If the
355    /// type has only static references, or none at all, then this may be chosen
356    /// to be `'static`.
357    ///
358    /// This function is mainly useful for data that lives for the remainder of
359    /// the program's life. Dropping the returned reference will cause a memory
360    /// leak. If this is not acceptable, the reference should first be wrapped
361    /// with the [`Box::from_raw_in`] function producing a `Box`. This `Box` can
362    /// then be dropped which will properly destroy `T` and release the
363    /// allocated memory.
364    ///
365    /// Note: this is an associated function, which means that you have to call
366    /// it as `Box::leak(b)` instead of `b.leak()`. This is so that there is no
367    /// conflict with a method on the inner type.
368    ///
369    /// # Examples
370    ///
371    /// Simple usage:
372    ///
373    /// ```
374    /// # #[cfg(not(miri))]
375    /// # fn main() -> Result<(), rune::alloc::Error> {
376    /// use rune::alloc::Box;
377    ///
378    /// let x = Box::try_new(41)?;
379    /// let static_ref: &'static mut usize = Box::leak(x);
380    /// *static_ref += 1;
381    /// assert_eq!(*static_ref, 42);
382    /// # Ok(())
383    /// # }
384    /// # #[cfg(miri)] fn main() {}
385    /// ```
386    ///
387    /// Unsized data:
388    ///
389    /// ```
390    /// # #[cfg(not(miri))]
391    /// # fn main() -> Result<(), rune::alloc::Error> {
392    /// use rune::alloc::{try_vec, Box};
393    ///
394    /// let x = try_vec![1, 2, 3].try_into_boxed_slice()?;
395    /// let static_ref = Box::leak(x);
396    /// static_ref[0] = 4;
397    /// assert_eq!(*static_ref, [4, 2, 3]);
398    /// # Ok(())
399    /// # }
400    /// # #[cfg(miri)] fn main() {}
401    /// ```
402    #[inline]
403    pub fn leak<'a>(b: Self) -> &'a mut T
404    where
405        A: 'a,
406    {
407        unsafe { &mut *mem::ManuallyDrop::new(b).ptr.as_ptr() }
408    }
409
410    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
411    /// `*boxed` will be pinned in memory and unable to be moved.
412    ///
413    /// This conversion does not allocate on the heap and happens in place.
414    ///
415    /// This is also available via [`From`].
416    ///
417    /// Constructing and pinning a `Box` with <code>Box::into_pin([Box::try?new]\(x))</code>
418    /// can also be written more concisely using <code>[Box::try?pin]\(x)</code>.
419    /// This `into_pin` method is useful if you already have a `Box<T>`, or you are
420    /// constructing a (pinned) `Box` in a different way than with [`Box::try_new`].
421    ///
422    /// # Notes
423    ///
424    /// It's not recommended that crates add an impl like `From<Box<T>> for Pin<T>`,
425    /// as it'll introduce an ambiguity when calling `Pin::from`.
426    /// A demonstration of such a poor impl is shown below.
427    ///
428    /// ```compile_fail
429    /// # use core::pin::Pin;
430    /// use rune::alloc::Box;
431    ///
432    /// struct Foo; // A type defined in this crate.
433    /// impl From<Box<()>> for Pin<Foo> {
434    ///     fn from(_: Box<()>) -> Pin<Foo> {
435    ///         Pin::new(Foo)
436    ///     }
437    /// }
438    ///
439    /// let foo = Box::try_new(())?;
440    /// let bar = Pin::from(foo);
441    /// # Ok::<_, rune::alloc::Error>(())
442    /// ```
443    pub fn into_pin(boxed: Self) -> Pin<Self>
444    where
445        A: 'static,
446    {
447        // It's not possible to move or replace the insides of a `Pin<Box<T>>`
448        // when `T: !Unpin`, so it's safe to pin it directly without any
449        // additional requirements.
450        unsafe { Pin::new_unchecked(boxed) }
451    }
452
453    /// Constructs a box from a raw pointer in the given allocator.
454    ///
455    /// After calling this function, the raw pointer is owned by the resulting
456    /// `Box`. Specifically, the `Box` destructor will call the destructor of
457    /// `T` and free the allocated memory. For this to be safe, the memory must
458    /// have been allocated in accordance with the [memory layout] used by `Box`
459    /// .
460    ///
461    /// # Safety
462    ///
463    /// This function is unsafe because improper use may lead to memory
464    /// problems. For example, a double-free may occur if the function is called
465    /// twice on the same raw pointer.
466    ///
467    /// # Examples
468    ///
469    /// Recreate a `Box` which was previously converted to a raw pointer using
470    /// [`Box::into_raw_with_allocator`]:
471    ///
472    /// ```
473    /// use rune::alloc::Box;
474    /// use rune::alloc::alloc::Global;
475    ///
476    /// let x = Box::try_new_in(5, Global)?;
477    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
478    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
479    /// # Ok::<_, rune::alloc::Error>(())
480    /// ```
481    ///
482    /// Manually create a `Box` from scratch by using the system allocator:
483    ///
484    /// ```
485    /// use core::alloc::Layout;
486    ///
487    /// use rune::alloc::Box;
488    /// use rune::alloc::alloc::{Allocator, Global};
489    ///
490    /// unsafe {
491    ///     let ptr = Global.allocate(Layout::new::<i32>())?.as_ptr() as *mut i32;
492    ///     // In general .write is required to avoid attempting to destruct
493    ///     // the (uninitialized) previous contents of `ptr`, though for this
494    ///     // simple example `*ptr = 5` would have worked as well.
495    ///     ptr.write(5);
496    ///     let x = Box::from_raw_in(ptr, Global);
497    /// }
498    /// # Ok::<_, rune::alloc::Error>(())
499    /// ```
500    ///
501    /// [memory layout]: self#memory-layout
502    /// [`Layout`]: core::alloc::Layout
503    #[inline]
504    pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
505        Self {
506            ptr: unsafe { Unique::new_unchecked(raw) },
507            alloc,
508        }
509    }
510
511    /// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
512    ///
513    /// The pointer will be properly aligned and non-null.
514    ///
515    /// After calling this function, the caller is responsible for the
516    /// memory previously managed by the `Box`. In particular, the
517    /// caller should properly destroy `T` and release the memory, taking
518    /// into account the [memory layout] used by `Box`. The easiest way to
519    /// do this is to convert the raw pointer back into a `Box` with the
520    /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform
521    /// the cleanup.
522    ///
523    /// Note: this is an associated function, which means that you have
524    /// to call it as `Box::into_raw_with_allocator(b)` instead of `b.into_raw_with_allocator()`. This
525    /// is so that there is no conflict with a method on the inner type.
526    ///
527    /// # Examples
528    ///
529    /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`]
530    /// for automatic cleanup:
531    ///
532    /// ```
533    /// use rune::alloc::{Box, String};
534    /// use rune::alloc::alloc::Global;
535    ///
536    /// let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
537    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
538    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
539    /// # Ok::<_, rune::alloc::Error>(())
540    /// ```
541    ///
542    /// Manual cleanup by explicitly running the destructor and deallocating the
543    /// memory:
544    ///
545    /// ```
546    /// use core::alloc::Layout;
547    /// use core::ptr::{self, NonNull};
548    ///
549    /// use rune::alloc::{Box, String};
550    /// use rune::alloc::alloc::{Allocator, Global};
551    ///
552    /// let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
553    ///
554    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
555    ///
556    /// unsafe {
557    ///     ptr::drop_in_place(ptr);
558    ///     let non_null = NonNull::new_unchecked(ptr);
559    ///     alloc.deallocate(non_null.cast(), Layout::new::<String>());
560    /// }
561    /// # Ok::<_, rune::alloc::Error>(())
562    /// ```
563    ///
564    /// [memory layout]: self#memory-layout
565    #[inline]
566    pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
567        let leaked = mem::ManuallyDrop::new(b);
568        // SAFETY: We prevent the alloc field from being dropped, so we can
569        // safely smuggle it out.
570        let alloc = unsafe { ptr::read(&leaked.alloc) };
571        (leaked.ptr.as_ptr(), alloc)
572    }
573
574    #[inline]
575    pub(crate) fn into_unique_with_allocator(b: Self) -> (Unique<T>, A) {
576        let (ptr, alloc) = Box::into_raw_with_allocator(b);
577        unsafe { (Unique::from(&mut *ptr), alloc) }
578    }
579}
580
581impl<T, A> Box<mem::MaybeUninit<T>, A>
582where
583    A: Allocator,
584{
585    /// Converts to `Box<T, A>`.
586    ///
587    /// # Safety
588    ///
589    /// As with [`MaybeUninit::assume_init`],
590    /// it is up to the caller to guarantee that the value
591    /// really is in an initialized state.
592    /// Calling this when the content is not yet fully initialized
593    /// causes immediate undefined behavior.
594    ///
595    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
596    ///
597    /// # Examples
598    ///
599    /// ```
600    /// use rune::alloc::Box;
601    /// use rune::alloc::alloc::Global;
602    ///
603    /// let mut five = Box::<u32>::try_new_uninit_in(Global)?;
604    ///
605    /// let five: Box<u32> = unsafe {
606    ///     // Deferred initialization:
607    ///     five.as_mut_ptr().write(5);
608    ///
609    ///     five.assume_init()
610    /// };
611    ///
612    /// assert_eq!(*five, 5);
613    /// # Ok::<_, rune::alloc::Error>(())
614    /// ```
615    #[inline]
616    pub unsafe fn assume_init(self) -> Box<T, A> {
617        let (raw, alloc) = Box::into_raw_with_allocator(self);
618        unsafe { Box::from_raw_in(raw as *mut T, alloc) }
619    }
620}
621
622impl<T, A> Box<[T], A>
623where
624    A: Allocator,
625{
626    /// Constructs a new boxed slice with uninitialized contents. Returns an error if
627    /// the allocation fails
628    ///
629    /// # Examples
630    ///
631    /// ```
632    /// use rune::alloc::Box;
633    /// use rune::alloc::alloc::Global;
634    ///
635    /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
636    ///
637    /// let values = unsafe {
638    ///     // Deferred initialization:
639    ///     values[0].as_mut_ptr().write(1);
640    ///     values[1].as_mut_ptr().write(2);
641    ///     values[2].as_mut_ptr().write(3);
642    ///     values.assume_init()
643    /// };
644    ///
645    /// assert_eq!(*values, [1, 2, 3]);
646    /// # Ok::<_, rune::alloc::Error>(())
647    /// ```
648    #[inline]
649    pub fn try_new_uninit_slice_in(
650        len: usize,
651        alloc: A,
652    ) -> Result<Box<[mem::MaybeUninit<T>], A>, Error> {
653        unsafe {
654            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
655                Ok(l) => l,
656                Err(_) => return Err(Error::LayoutError),
657            };
658            let ptr = alloc.allocate(layout)?;
659            Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, alloc).into_box(len))
660        }
661    }
662}
663
664impl<T, A> Box<[mem::MaybeUninit<T>], A>
665where
666    A: Allocator,
667{
668    /// Converts to `Box<[T], A>`.
669    ///
670    /// # Safety
671    ///
672    /// As with [`MaybeUninit::assume_init`],
673    /// it is up to the caller to guarantee that the values
674    /// really are in an initialized state.
675    /// Calling this when the content is not yet fully initialized
676    /// causes immediate undefined behavior.
677    ///
678    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
679    ///
680    /// # Examples
681    ///
682    /// ```
683    /// use rune::alloc::Box;
684    /// use rune::alloc::alloc::Global;
685    ///
686    /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
687    ///
688    /// let values = unsafe {
689    ///     // Deferred initialization:
690    ///     values[0].as_mut_ptr().write(1);
691    ///     values[1].as_mut_ptr().write(2);
692    ///     values[2].as_mut_ptr().write(3);
693    ///     values.assume_init()
694    /// };
695    ///
696    /// assert_eq!(*values, [1, 2, 3]);
697    /// # Ok::<_, rune::alloc::Error>(())
698    /// ```
699    #[inline]
700    pub unsafe fn assume_init(self) -> Box<[T], A> {
701        let (raw, alloc) = Box::into_raw_with_allocator(self);
702        unsafe { Box::from_raw_in(raw as *mut [T], alloc) }
703    }
704}
705
706impl<T, A> TryClone for Box<T, A>
707where
708    T: TryClone,
709    A: Allocator + Clone,
710{
711    #[inline]
712    fn try_clone(&self) -> Result<Self, Error> {
713        let value = (**self).try_clone()?;
714        let alloc = self.alloc.clone();
715        Ok(Box::try_new_in(value, alloc)?)
716    }
717}
718
719impl<T, A> TryClone for Box<[T], A>
720where
721    T: TryClone,
722    A: Allocator + Clone,
723{
724    #[inline]
725    fn try_clone(&self) -> Result<Self, Error> {
726        let alloc = self.alloc.clone();
727        let vec = crate::slice::to_vec(self, alloc)?;
728        vec.try_into_boxed_slice()
729    }
730}
731
732impl<A> TryClone for Box<str, A>
733where
734    A: Allocator + Clone,
735{
736    #[inline]
737    fn try_clone(&self) -> Result<Self, Error> {
738        let alloc = self.alloc.clone();
739        Box::try_from_string_in(self.as_ref(), alloc)
740    }
741}
742
743impl<T, A> Borrow<T> for Box<T, A>
744where
745    T: ?Sized,
746    A: Allocator,
747{
748    #[inline]
749    fn borrow(&self) -> &T {
750        self
751    }
752}
753
754impl<T, A> BorrowMut<T> for Box<T, A>
755where
756    T: ?Sized,
757    A: Allocator,
758{
759    #[inline]
760    fn borrow_mut(&mut self) -> &mut T {
761        self
762    }
763}
764
765impl<T, A> AsRef<T> for Box<T, A>
766where
767    T: ?Sized,
768    A: Allocator,
769{
770    #[inline]
771    fn as_ref(&self) -> &T {
772        self
773    }
774}
775
776impl<T, A> AsMut<T> for Box<T, A>
777where
778    T: ?Sized,
779    A: Allocator,
780{
781    #[inline]
782    fn as_mut(&mut self) -> &mut T {
783        self
784    }
785}
786
787/* Nota bene
788 *
789 *  We could have chosen not to add this impl, and instead have written a
790 *  function of Pin<Box<T>> to Pin<T>. Such a function would not be sound,
791 *  because Box<T> implements Unpin even when T does not, as a result of
792 *  this impl.
793 *
794 *  We chose this API instead of the alternative for a few reasons:
795 *      - Logically, it is helpful to understand pinning in regard to the
796 *        memory region being pointed to. For this reason none of the
797 *        standard library pointer types support projecting through a pin
798 *        (Box<T> is the only pointer type in std for which this would be
799 *        safe.)
800 *      - It is in practice very useful to have Box<T> be unconditionally
801 *        Unpin because of trait objects, for which the structural auto
802 *        trait functionality does not apply (e.g., Box<dyn Foo> would
803 *        otherwise not be Unpin).
804 *
805 *  Another type with the same semantics as Box but only a conditional
806 *  implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and
807 *  could have a method to project a Pin<T> from it.
808 */
809impl<T, A> Unpin for Box<T, A>
810where
811    A: 'static,
812    T: ?Sized,
813    A: Allocator,
814{
815}
816
817impl<T, A> Deref for Box<T, A>
818where
819    T: ?Sized,
820    A: Allocator,
821{
822    type Target = T;
823
824    #[inline]
825    fn deref(&self) -> &T {
826        unsafe { self.ptr.as_ref() }
827    }
828}
829
830impl<T, A> DerefMut for Box<T, A>
831where
832    T: ?Sized,
833    A: Allocator,
834{
835    #[inline]
836    fn deref_mut(&mut self) -> &mut T {
837        unsafe { self.ptr.as_mut() }
838    }
839}
840
841impl<T, A> Drop for Box<T, A>
842where
843    T: ?Sized,
844    A: Allocator,
845{
846    #[inline]
847    fn drop(&mut self) {
848        unsafe {
849            let ptr = self.ptr;
850
851            if mem::needs_drop::<T>() {
852                ptr::drop_in_place(ptr.as_ptr());
853            }
854
855            let layout = for_value_raw(ptr.as_ptr());
856
857            if layout.size() != 0 {
858                self.alloc.deallocate(From::from(ptr.cast()), layout);
859            }
860        }
861    }
862}
863
864impl Default for Box<str, Global> {
865    #[inline]
866    fn default() -> Self {
867        // SAFETY: The layout of `Box<[u8]>` is the same as `Box<str>`.
868        unsafe {
869            let b = Box::<[u8]>::default();
870            let (ptr, alloc) = Box::into_raw_with_allocator(b);
871            Box::from_raw_in(ptr as *mut str, alloc)
872        }
873    }
874}
875
876impl<T> Default for Box<[T], Global> {
877    #[inline]
878    fn default() -> Self {
879        Box {
880            ptr: Unique::dangling_empty_slice(),
881            alloc: Global,
882        }
883    }
884}
885
886impl<T, A> fmt::Display for Box<T, A>
887where
888    T: ?Sized + fmt::Display,
889    A: Allocator,
890{
891    #[inline]
892    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
893        (**self).fmt(f)
894    }
895}
896
897impl<T, A> fmt::Debug for Box<T, A>
898where
899    T: ?Sized + fmt::Debug,
900    A: Allocator,
901{
902    #[inline]
903    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
904        (**self).fmt(f)
905    }
906}
907
908impl<A> From<Box<str, A>> for Box<[u8], A>
909where
910    A: Allocator,
911{
912    fn from(value: Box<str, A>) -> Self {
913        // SAFETY: `[u8]` is layout compatible with `str` and there are no
914        // checks needed.
915        unsafe {
916            let (ptr, alloc) = Box::into_raw_with_allocator(value);
917            Box::from_raw_in(ptr as *mut [u8], alloc)
918        }
919    }
920}
921
922impl<T, const N: usize> TryFrom<[T; N]> for Box<[T]> {
923    type Error = Error;
924
925    #[inline]
926    fn try_from(values: [T; N]) -> Result<Self, Self::Error> {
927        let mut vec = Vec::try_with_capacity(values.len())?;
928
929        for value in values {
930            vec.try_push(value)?;
931        }
932
933        vec.try_into_boxed_slice()
934    }
935}
936
937/// Casts a boxed slice to a boxed array.
938///
939/// # Safety
940///
941/// `boxed_slice.len()` must be exactly `N`.
942unsafe fn boxed_slice_as_array_unchecked<T, A, const N: usize>(
943    boxed_slice: Box<[T], A>,
944) -> Box<[T; N], A>
945where
946    A: Allocator,
947{
948    debug_assert_eq!(boxed_slice.len(), N);
949
950    let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
951    // SAFETY: Pointer and allocator came from an existing box,
952    // and our safety condition requires that the length is exactly `N`
953    unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) }
954}
955
956impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
957    type Error = Box<[T]>;
958
959    /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
960    ///
961    /// The conversion occurs in-place and does not require a
962    /// new memory allocation.
963    ///
964    /// # Errors
965    ///
966    /// Returns the old `Box<[T]>` in the `Err` variant if
967    /// `boxed_slice.len()` does not equal `N`.
968    fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
969        if boxed_slice.len() == N {
970            Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
971        } else {
972            Err(boxed_slice)
973        }
974    }
975}
976
977impl<T, A> TryFrom<Vec<T, A>> for Box<[T], A>
978where
979    A: Allocator,
980{
981    type Error = Error;
982
983    #[inline]
984    fn try_from(vec: Vec<T, A>) -> Result<Self, Error> {
985        vec.try_into_boxed_slice()
986    }
987}
988
989impl<A> Box<[u8], A>
990where
991    A: Allocator,
992{
993    #[inline]
994    pub(crate) fn try_from_bytes_in(bytes: &[u8], alloc: A) -> Result<Self, Error> {
995        let mut vec = Vec::<u8, A>::try_with_capacity_in(bytes.len(), alloc)?;
996
997        unsafe {
998            ptr::copy_nonoverlapping(bytes.as_ptr(), vec.as_mut_ptr(), bytes.len());
999            vec.set_len(bytes.len());
1000            vec.try_into_boxed_slice()
1001        }
1002    }
1003}
1004
1005impl<A> Box<str, A>
1006where
1007    A: Allocator,
1008{
1009    #[inline]
1010    pub(crate) fn try_from_string_in(string: &str, alloc: A) -> Result<Self, Error> {
1011        unsafe {
1012            let b = Box::try_from_bytes_in(string.as_bytes(), alloc)?;
1013            let (raw, alloc) = Box::into_raw_with_allocator(b);
1014            Ok(Box::from_raw_in(raw as *mut str, alloc))
1015        }
1016    }
1017}
1018
1019impl<A> Box<Path, A>
1020where
1021    A: Allocator,
1022{
1023    #[inline]
1024    pub(crate) fn try_from_path_in(path: &Path, alloc: A) -> Result<Self, Error> {
1025        unsafe {
1026            const _: () = assert!(mem::size_of::<&Path>() == mem::size_of::<&[u8]>());
1027            // Replace with path.as_os_str().as_encoded_bytes() once that is
1028            // stable.
1029            let bytes = &*(path as *const _ as *const [u8]);
1030            let b = Box::try_from_bytes_in(bytes, alloc)?;
1031            let (raw, alloc) = Box::into_raw_with_allocator(b);
1032            Ok(Box::from_raw_in(raw as *mut Path, alloc))
1033        }
1034    }
1035}
1036
1037impl<A> TryClone for Box<Path, A>
1038where
1039    A: Allocator + Clone,
1040{
1041    #[inline]
1042    fn try_clone(&self) -> Result<Self, Error> {
1043        let alloc = self.alloc.clone();
1044        Box::try_from_path_in(self.as_ref(), alloc)
1045    }
1046}
1047
1048impl TryFrom<&str> for Box<str> {
1049    type Error = Error;
1050
1051    /// Converts a `&str` into a `Box<str>`.
1052    ///
1053    /// # Examples
1054    ///
1055    /// ```
1056    /// use rune::alloc::Box;
1057    ///
1058    /// let s: Box<str> = Box::try_from("Hello World")?;
1059    /// assert_eq!(s.as_ref(), "Hello World");
1060    /// # Ok::<_, rune::alloc::Error>(())
1061    /// ```
1062    #[inline]
1063    fn try_from(values: &str) -> Result<Self, Error> {
1064        Box::try_from_string_in(values, Global)
1065    }
1066}
1067
1068#[cfg(feature = "alloc")]
1069impl TryFrom<rust_alloc::string::String> for Box<str> {
1070    type Error = Error;
1071
1072    /// Converts a std `String` into a `Box<str>`.
1073    ///
1074    /// # Examples
1075    ///
1076    /// ```
1077    /// use rune::alloc::Box;
1078    ///
1079    /// let s = String::from("Hello World");
1080    /// let s: Box<str> = Box::try_from(s)?;
1081    /// assert_eq!(s.as_ref(), "Hello World");
1082    /// # Ok::<_, rune::alloc::Error>(())
1083    /// ```
1084    #[inline]
1085    fn try_from(string: rust_alloc::string::String) -> Result<Self, Error> {
1086        Box::from_std(string.into_boxed_str())
1087    }
1088}
1089
1090impl TryFrom<&[u8]> for Box<[u8]> {
1091    type Error = Error;
1092
1093    /// Converts a `&[u8]` into a `Box<[u8]>`.
1094    ///
1095    /// # Examples
1096    ///
1097    /// ```
1098    /// use rune::alloc::Box;
1099    ///
1100    /// let s: Box<[u8]> = Box::try_from(&b"Hello World"[..])?;
1101    /// assert_eq!(s.as_ref(), b"Hello World");
1102    /// # Ok::<_, rune::alloc::Error>(())
1103    /// ```
1104    #[inline]
1105    fn try_from(values: &[u8]) -> Result<Self, Self::Error> {
1106        Box::try_from_bytes_in(values, Global)
1107    }
1108}
1109
1110impl TryFrom<&Path> for Box<Path> {
1111    type Error = Error;
1112
1113    /// Converts a `&[u8]` into a `Box<[u8]>`.
1114    ///
1115    /// # Examples
1116    ///
1117    /// ```
1118    /// use std::path::Path;
1119    /// use rune::alloc::Box;
1120    ///
1121    /// let path = Path::new("foo/bar");
1122    ///
1123    /// let s: Box<Path> = Box::try_from(path)?;
1124    /// assert_eq!(s.as_ref(), Path::new("foo/bar"));
1125    /// # Ok::<_, rune::alloc::Error>(())
1126    /// ```
1127    #[inline]
1128    fn try_from(path: &Path) -> Result<Self, Error> {
1129        Box::try_from_path_in(path, Global)
1130    }
1131}
1132
1133impl<T, A> TryFromIteratorIn<T, A> for Box<[T], A>
1134where
1135    A: Allocator,
1136{
1137    #[inline]
1138    fn try_from_iter_in<I>(iter: I, alloc: A) -> Result<Self, Error>
1139    where
1140        I: IntoIterator<Item = T>,
1141    {
1142        Vec::<T, A>::try_from_iter_in(iter, alloc)?.try_into_boxed_slice()
1143    }
1144}
1145
1146unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Layout {
1147    // SAFETY: we pass along the prerequisites of these functions to the caller
1148    // TODO: Use mem::{size_of_val_raw, align_of_val_raw} when they become
1149    // stable, for now we privately know that this can safely be turned into a
1150    // reference since it's only used while dropping an owned value of type `T`.
1151    let (size, align) = (mem::size_of_val(&*t), mem::align_of_val(&*t));
1152    // SAFETY: see rationale in `new` for why this is using the unsafe variant
1153    Layout::from_size_align_unchecked(size, align)
1154}
1155
1156impl<T, A> Hash for Box<T, A>
1157where
1158    T: ?Sized + Hash,
1159    A: Allocator,
1160{
1161    #[inline]
1162    fn hash<H>(&self, state: &mut H)
1163    where
1164        H: Hasher,
1165    {
1166        (**self).hash(state);
1167    }
1168}
1169
1170impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>
1171where
1172    T: ?Sized,
1173    A: 'static + Allocator,
1174{
1175    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement
1176    /// [`Unpin`], then `*boxed` will be pinned in memory and unable to be
1177    /// moved.
1178    ///
1179    /// This conversion does not allocate on the heap and happens in place.
1180    ///
1181    /// This is also available via [`Box::into_pin`].
1182    ///
1183    /// Constructing and pinning a `Box` with
1184    /// <code><Pin<Box\<T>>>::from([Box::try?new]\(x))</code> can also be
1185    /// written more concisely using <code>[Box::try?pin]\(x)</code>. This
1186    /// `From` implementation is useful if you already have a `Box<T>`, or you
1187    /// are constructing a (pinned) `Box` in a different way than with
1188    /// [`Box::try_new`].
1189    #[inline]
1190    fn from(boxed: Box<T, A>) -> Self {
1191        Box::into_pin(boxed)
1192    }
1193}
1194
1195impl<T, A> PartialEq for Box<T, A>
1196where
1197    T: ?Sized + PartialEq,
1198    A: Allocator,
1199{
1200    #[inline]
1201    fn eq(&self, other: &Self) -> bool {
1202        (**self).eq(other)
1203    }
1204}
1205
1206impl<T, A> Eq for Box<T, A>
1207where
1208    T: ?Sized + Eq,
1209    A: Allocator,
1210{
1211}
1212
1213impl<T, A> PartialOrd for Box<T, A>
1214where
1215    T: ?Sized + PartialOrd,
1216    A: Allocator,
1217{
1218    #[inline]
1219    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1220        (**self).partial_cmp(other)
1221    }
1222}
1223
1224impl<T, A> Ord for Box<T, A>
1225where
1226    T: ?Sized + Ord,
1227    A: Allocator,
1228{
1229    #[inline]
1230    fn cmp(&self, other: &Self) -> Ordering {
1231        (**self).cmp(other)
1232    }
1233}
1234
1235#[cfg(feature = "alloc")]
1236impl<T> TryFrom<rust_alloc::boxed::Box<[T]>> for Box<[T]> {
1237    type Error = Error;
1238
1239    #[inline]
1240    fn try_from(values: rust_alloc::boxed::Box<[T]>) -> Result<Self, Self::Error> {
1241        let mut vec = Vec::try_with_capacity(values.len())?;
1242
1243        for value in rust_alloc::vec::Vec::from(values) {
1244            vec.try_push(value)?;
1245        }
1246
1247        vec.try_into_boxed_slice()
1248    }
1249}