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: ?Sized, A: Allocator = Global> {
186    ptr: Unique<T>,
187    alloc: A,
188}
189
190impl<T> Box<T, Global> {
191    /// Allocates memory on the heap and then places `x` into it.
192    ///
193    /// This doesn't actually allocate if `T` is zero-sized.
194    ///
195    /// # Examples
196    ///
197    /// ```
198    /// use rune::alloc::Box;
199    ///
200    /// let five = Box::try_new(5)?;
201    /// # Ok::<_, rune::alloc::Error>(())
202    /// ```
203    pub fn try_new(value: T) -> Result<Self, AllocError> {
204        Self::try_new_in(value, Global)
205    }
206
207    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement [`Unpin`],
208    /// then `x` will be pinned in memory and unable to be moved.
209    ///
210    /// Constructing and pinning of the `Box` can also be done in two steps:
211    /// `Box::try?pin(x)` does the same as
212    /// <code>[Box::into_pin]\([Box::try?new]\(x))</code>. Consider using
213    /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, or if you
214    /// want to construct a (pinned) `Box` in a different way than with
215    /// [`Box::try_new`].
216    #[inline(always)]
217    pub fn try_pin(x: T) -> Result<Pin<Box<T>>, AllocError> {
218        Ok(Box::try_new(x)?.into())
219    }
220}
221
222impl<T: ?Sized> Box<T> {
223    /// Convert from a std `Box`.
224    ///
225    /// This causes the underlying allocation to be accounted for by the
226    /// [`Global`] allocator.
227    ///
228    /// A caveat of this method is that the allocation is already in use, but
229    /// this might still be necessary because we want access to certain methods
230    /// in std `Box` such as the ability to coerce to unsized values.
231    ///
232    /// # Examples
233    ///
234    /// ```
235    /// use rune::alloc::{Box, Vec};
236    /// use rune::alloc::limit;
237    /// use std::boxed::Box as StdBox;
238    ///
239    /// assert_eq!(limit::get(), usize::MAX);
240    ///
241    /// let b: StdBox<dyn Iterator<Item = u32>> = StdBox::new(1..3);
242    /// let mut b = Box::from_std(b)?;
243    /// assert_eq!(b.next(), Some(1));
244    /// assert_eq!(b.next(), Some(2));
245    /// assert_eq!(b.next(), None);
246    ///
247    /// assert!(limit::get() < usize::MAX);
248    /// drop(b);
249    ///
250    /// assert_eq!(limit::get(), usize::MAX);
251    /// # Ok::<_, rune::alloc::Error>(())
252    /// ```
253    #[cfg(feature = "alloc")]
254    pub fn from_std(b: ::rust_alloc::boxed::Box<T>) -> Result<Self, Error> {
255        // SAFETY: We've ensured that standard allocations only happen in an
256        // allocator which is compatible with our `Global`.
257        unsafe {
258            // NB: Layout::for_value will return the size of the pointed to
259            // value by the box, which for unsized types is the size of the
260            // metadata. For sized types the value inside of the box.
261            Global.take(Layout::for_value(b.as_ref()))?;
262            let raw = ::rust_alloc::boxed::Box::into_raw(b);
263            Ok(Box::from_raw_in(raw, Global))
264        }
265    }
266}
267
268impl<T, A: Allocator> Box<T, A> {
269    /// Allocates memory in the given allocator then places `x` into it,
270    /// returning an error if the allocation fails
271    ///
272    /// This doesn't actually allocate if `T` is zero-sized.
273    ///
274    /// # Examples
275    ///
276    /// ```
277    /// use rune::alloc::Box;
278    /// use rune::alloc::alloc::Global;
279    ///
280    /// let five = Box::try_new_in(5, Global)?;
281    /// # Ok::<_, rune::alloc::Error>(())
282    /// ```
283    #[inline]
284    pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
285        let mut boxed = Self::try_new_uninit_in(alloc)?;
286
287        unsafe {
288            boxed.as_mut_ptr().write(x);
289            Ok(boxed.assume_init())
290        }
291    }
292
293    /// Constructs a new box with uninitialized contents in the provided
294    /// allocator, returning an error if the allocation fails
295    ///
296    /// # Examples
297    ///
298    /// ```
299    /// use rune::alloc::Box;
300    /// use rune::alloc::alloc::Global;
301    ///
302    /// let mut five = Box::<u32>::try_new_uninit_in(Global)?;
303    ///
304    /// let five: Box<u32> = unsafe {
305    ///     // Deferred initialization:
306    ///     five.as_mut_ptr().write(5);
307    ///
308    ///     five.assume_init()
309    /// };
310    ///
311    /// assert_eq!(*five, 5);
312    /// # Ok::<_, rune::alloc::Error>(())
313    /// ```
314    pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
315    where
316        A: Allocator,
317    {
318        let layout = Layout::new::<mem::MaybeUninit<T>>();
319        let ptr = alloc.allocate(layout)?.cast();
320        unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
321    }
322
323    /// Consumes the `Box`, returning the wrapped value.
324    #[inline]
325    pub fn into_inner(boxed: Self) -> T {
326        let this = mem::ManuallyDrop::new(boxed);
327        let value = unsafe { ptr::read(this.ptr.as_ptr()) };
328
329        // Free memory associated with the box.
330        //
331        // SAFETY: We own the box, so we know we can safely deallocate it.
332        unsafe {
333            let layout = for_value_raw(this.ptr.as_ptr());
334
335            if layout.size() != 0 {
336                this.alloc.deallocate(From::from(this.ptr.cast()), layout);
337            }
338        }
339
340        value
341    }
342}
343
344impl<T: ?Sized, A: Allocator> Box<T, A> {
345    /// Consumes and leaks the `Box`, returning a mutable reference, `&'a mut
346    /// T`. Note that the type `T` must outlive the chosen lifetime `'a`. If the
347    /// type has only static references, or none at all, then this may be chosen
348    /// to be `'static`.
349    ///
350    /// This function is mainly useful for data that lives for the remainder of
351    /// the program's life. Dropping the returned reference will cause a memory
352    /// leak. If this is not acceptable, the reference should first be wrapped
353    /// with the [`Box::from_raw_in`] function producing a `Box`. This `Box` can
354    /// then be dropped which will properly destroy `T` and release the
355    /// allocated memory.
356    ///
357    /// Note: this is an associated function, which means that you have to call
358    /// it as `Box::leak(b)` instead of `b.leak()`. This is so that there is no
359    /// conflict with a method on the inner type.
360    ///
361    /// # Examples
362    ///
363    /// Simple usage:
364    ///
365    /// ```
366    /// # #[cfg(not(miri))]
367    /// # fn main() -> Result<(), rune::alloc::Error> {
368    /// use rune::alloc::Box;
369    ///
370    /// let x = Box::try_new(41)?;
371    /// let static_ref: &'static mut usize = Box::leak(x);
372    /// *static_ref += 1;
373    /// assert_eq!(*static_ref, 42);
374    /// # Ok(())
375    /// # }
376    /// # #[cfg(miri)] fn main() {}
377    /// ```
378    ///
379    /// Unsized data:
380    ///
381    /// ```
382    /// # #[cfg(not(miri))]
383    /// # fn main() -> Result<(), rune::alloc::Error> {
384    /// use rune::alloc::{try_vec, Box};
385    ///
386    /// let x = try_vec![1, 2, 3].try_into_boxed_slice()?;
387    /// let static_ref = Box::leak(x);
388    /// static_ref[0] = 4;
389    /// assert_eq!(*static_ref, [4, 2, 3]);
390    /// # Ok(())
391    /// # }
392    /// # #[cfg(miri)] fn main() {}
393    /// ```
394    #[inline]
395    pub fn leak<'a>(b: Self) -> &'a mut T
396    where
397        A: 'a,
398    {
399        unsafe { &mut *mem::ManuallyDrop::new(b).ptr.as_ptr() }
400    }
401
402    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
403    /// `*boxed` will be pinned in memory and unable to be moved.
404    ///
405    /// This conversion does not allocate on the heap and happens in place.
406    ///
407    /// This is also available via [`From`].
408    ///
409    /// Constructing and pinning a `Box` with <code>Box::into_pin([Box::try?new]\(x))</code>
410    /// can also be written more concisely using <code>[Box::try?pin]\(x)</code>.
411    /// This `into_pin` method is useful if you already have a `Box<T>`, or you are
412    /// constructing a (pinned) `Box` in a different way than with [`Box::try_new`].
413    ///
414    /// # Notes
415    ///
416    /// It's not recommended that crates add an impl like `From<Box<T>> for Pin<T>`,
417    /// as it'll introduce an ambiguity when calling `Pin::from`.
418    /// A demonstration of such a poor impl is shown below.
419    ///
420    /// ```compile_fail
421    /// # use core::pin::Pin;
422    /// use rune::alloc::Box;
423    ///
424    /// struct Foo; // A type defined in this crate.
425    /// impl From<Box<()>> for Pin<Foo> {
426    ///     fn from(_: Box<()>) -> Pin<Foo> {
427    ///         Pin::new(Foo)
428    ///     }
429    /// }
430    ///
431    /// let foo = Box::try_new(())?;
432    /// let bar = Pin::from(foo);
433    /// # Ok::<_, rune::alloc::Error>(())
434    /// ```
435    pub fn into_pin(boxed: Self) -> Pin<Self>
436    where
437        A: 'static,
438    {
439        // It's not possible to move or replace the insides of a `Pin<Box<T>>`
440        // when `T: !Unpin`, so it's safe to pin it directly without any
441        // additional requirements.
442        unsafe { Pin::new_unchecked(boxed) }
443    }
444
445    /// Constructs a box from a raw pointer in the given allocator.
446    ///
447    /// After calling this function, the raw pointer is owned by the resulting
448    /// `Box`. Specifically, the `Box` destructor will call the destructor of
449    /// `T` and free the allocated memory. For this to be safe, the memory must
450    /// have been allocated in accordance with the [memory layout] used by `Box`
451    /// .
452    ///
453    /// # Safety
454    ///
455    /// This function is unsafe because improper use may lead to memory
456    /// problems. For example, a double-free may occur if the function is called
457    /// twice on the same raw pointer.
458    ///
459    /// # Examples
460    ///
461    /// Recreate a `Box` which was previously converted to a raw pointer using
462    /// [`Box::into_raw_with_allocator`]:
463    ///
464    /// ```
465    /// use rune::alloc::Box;
466    /// use rune::alloc::alloc::Global;
467    ///
468    /// let x = Box::try_new_in(5, Global)?;
469    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
470    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
471    /// # Ok::<_, rune::alloc::Error>(())
472    /// ```
473    ///
474    /// Manually create a `Box` from scratch by using the system allocator:
475    ///
476    /// ```
477    /// use core::alloc::Layout;
478    ///
479    /// use rune::alloc::Box;
480    /// use rune::alloc::alloc::{Allocator, Global};
481    ///
482    /// unsafe {
483    ///     let ptr = Global.allocate(Layout::new::<i32>())?.as_ptr() as *mut i32;
484    ///     // In general .write is required to avoid attempting to destruct
485    ///     // the (uninitialized) previous contents of `ptr`, though for this
486    ///     // simple example `*ptr = 5` would have worked as well.
487    ///     ptr.write(5);
488    ///     let x = Box::from_raw_in(ptr, Global);
489    /// }
490    /// # Ok::<_, rune::alloc::Error>(())
491    /// ```
492    ///
493    /// [memory layout]: self#memory-layout
494    /// [`Layout`]: core::alloc::Layout
495    #[inline]
496    pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
497        Self {
498            ptr: unsafe { Unique::new_unchecked(raw) },
499            alloc,
500        }
501    }
502
503    /// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
504    ///
505    /// The pointer will be properly aligned and non-null.
506    ///
507    /// After calling this function, the caller is responsible for the
508    /// memory previously managed by the `Box`. In particular, the
509    /// caller should properly destroy `T` and release the memory, taking
510    /// into account the [memory layout] used by `Box`. The easiest way to
511    /// do this is to convert the raw pointer back into a `Box` with the
512    /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform
513    /// the cleanup.
514    ///
515    /// Note: this is an associated function, which means that you have
516    /// to call it as `Box::into_raw_with_allocator(b)` instead of `b.into_raw_with_allocator()`. This
517    /// is so that there is no conflict with a method on the inner type.
518    ///
519    /// # Examples
520    ///
521    /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`]
522    /// for automatic cleanup:
523    ///
524    /// ```
525    /// use rune::alloc::{Box, String};
526    /// use rune::alloc::alloc::Global;
527    ///
528    /// let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
529    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
530    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
531    /// # Ok::<_, rune::alloc::Error>(())
532    /// ```
533    ///
534    /// Manual cleanup by explicitly running the destructor and deallocating the
535    /// memory:
536    ///
537    /// ```
538    /// use core::alloc::Layout;
539    /// use core::ptr::{self, NonNull};
540    ///
541    /// use rune::alloc::{Box, String};
542    /// use rune::alloc::alloc::{Allocator, Global};
543    ///
544    /// let x = Box::try_new_in(String::try_from("Hello")?, Global)?;
545    ///
546    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
547    ///
548    /// unsafe {
549    ///     ptr::drop_in_place(ptr);
550    ///     let non_null = NonNull::new_unchecked(ptr);
551    ///     alloc.deallocate(non_null.cast(), Layout::new::<String>());
552    /// }
553    /// # Ok::<_, rune::alloc::Error>(())
554    /// ```
555    ///
556    /// [memory layout]: self#memory-layout
557    #[inline]
558    pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
559        let leaked = mem::ManuallyDrop::new(b);
560        // SAFETY: We prevent the alloc field from being dropped, so we can
561        // safely smuggle it out.
562        let alloc = unsafe { ptr::read(&leaked.alloc) };
563        (leaked.ptr.as_ptr(), alloc)
564    }
565}
566
567impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
568    /// Converts to `Box<T, A>`.
569    ///
570    /// # Safety
571    ///
572    /// As with [`MaybeUninit::assume_init`],
573    /// it is up to the caller to guarantee that the value
574    /// really is in an initialized state.
575    /// Calling this when the content is not yet fully initialized
576    /// causes immediate undefined behavior.
577    ///
578    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// use rune::alloc::Box;
584    /// use rune::alloc::alloc::Global;
585    ///
586    /// let mut five = Box::<u32>::try_new_uninit_in(Global)?;
587    ///
588    /// let five: Box<u32> = unsafe {
589    ///     // Deferred initialization:
590    ///     five.as_mut_ptr().write(5);
591    ///
592    ///     five.assume_init()
593    /// };
594    ///
595    /// assert_eq!(*five, 5);
596    /// # Ok::<_, rune::alloc::Error>(())
597    /// ```
598    #[inline]
599    pub unsafe fn assume_init(self) -> Box<T, A> {
600        let (raw, alloc) = Box::into_raw_with_allocator(self);
601        unsafe { Box::from_raw_in(raw as *mut T, alloc) }
602    }
603}
604
605impl<T, A: Allocator> Box<[T], A> {
606    /// Constructs a new boxed slice with uninitialized contents. Returns an error if
607    /// the allocation fails
608    ///
609    /// # Examples
610    ///
611    /// ```
612    /// use rune::alloc::Box;
613    /// use rune::alloc::alloc::Global;
614    ///
615    /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
616    ///
617    /// let values = unsafe {
618    ///     // Deferred initialization:
619    ///     values[0].as_mut_ptr().write(1);
620    ///     values[1].as_mut_ptr().write(2);
621    ///     values[2].as_mut_ptr().write(3);
622    ///     values.assume_init()
623    /// };
624    ///
625    /// assert_eq!(*values, [1, 2, 3]);
626    /// # Ok::<_, rune::alloc::Error>(())
627    /// ```
628    #[inline]
629    pub fn try_new_uninit_slice_in(
630        len: usize,
631        alloc: A,
632    ) -> Result<Box<[mem::MaybeUninit<T>], A>, Error> {
633        unsafe {
634            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
635                Ok(l) => l,
636                Err(_) => return Err(Error::LayoutError),
637            };
638            let ptr = alloc.allocate(layout)?;
639            Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, alloc).into_box(len))
640        }
641    }
642}
643
644impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
645    /// Converts to `Box<[T], A>`.
646    ///
647    /// # Safety
648    ///
649    /// As with [`MaybeUninit::assume_init`],
650    /// it is up to the caller to guarantee that the values
651    /// really are in an initialized state.
652    /// Calling this when the content is not yet fully initialized
653    /// causes immediate undefined behavior.
654    ///
655    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
656    ///
657    /// # Examples
658    ///
659    /// ```
660    /// use rune::alloc::Box;
661    /// use rune::alloc::alloc::Global;
662    ///
663    /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, Global)?;
664    ///
665    /// let values = unsafe {
666    ///     // Deferred initialization:
667    ///     values[0].as_mut_ptr().write(1);
668    ///     values[1].as_mut_ptr().write(2);
669    ///     values[2].as_mut_ptr().write(3);
670    ///     values.assume_init()
671    /// };
672    ///
673    /// assert_eq!(*values, [1, 2, 3]);
674    /// # Ok::<_, rune::alloc::Error>(())
675    /// ```
676    #[inline]
677    pub unsafe fn assume_init(self) -> Box<[T], A> {
678        let (raw, alloc) = Box::into_raw_with_allocator(self);
679        unsafe { Box::from_raw_in(raw as *mut [T], alloc) }
680    }
681}
682
683impl<T, A: Allocator + Clone> TryClone for Box<T, A>
684where
685    T: TryClone,
686{
687    #[inline]
688    fn try_clone(&self) -> Result<Self, Error> {
689        let value = (**self).try_clone()?;
690        let alloc = self.alloc.clone();
691        Ok(Box::try_new_in(value, alloc)?)
692    }
693}
694
695impl<T, A: Allocator + Clone> TryClone for Box<[T], A>
696where
697    T: TryClone,
698{
699    #[inline]
700    fn try_clone(&self) -> Result<Self, Error> {
701        let alloc = self.alloc.clone();
702        let vec = crate::slice::to_vec(self, alloc)?;
703        vec.try_into_boxed_slice()
704    }
705}
706
707impl<A: Allocator + Clone> TryClone for Box<str, A> {
708    #[inline]
709    fn try_clone(&self) -> Result<Self, Error> {
710        let alloc = self.alloc.clone();
711        Box::try_from_string_in(self.as_ref(), alloc)
712    }
713}
714
715impl<T: ?Sized, A: Allocator> Borrow<T> for Box<T, A> {
716    fn borrow(&self) -> &T {
717        self
718    }
719}
720
721impl<T: ?Sized, A: Allocator> BorrowMut<T> for Box<T, A> {
722    fn borrow_mut(&mut self) -> &mut T {
723        self
724    }
725}
726
727impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> {
728    fn as_ref(&self) -> &T {
729        self
730    }
731}
732
733impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
734    fn as_mut(&mut self) -> &mut T {
735        self
736    }
737}
738
739/* Nota bene
740 *
741 *  We could have chosen not to add this impl, and instead have written a
742 *  function of Pin<Box<T>> to Pin<T>. Such a function would not be sound,
743 *  because Box<T> implements Unpin even when T does not, as a result of
744 *  this impl.
745 *
746 *  We chose this API instead of the alternative for a few reasons:
747 *      - Logically, it is helpful to understand pinning in regard to the
748 *        memory region being pointed to. For this reason none of the
749 *        standard library pointer types support projecting through a pin
750 *        (Box<T> is the only pointer type in std for which this would be
751 *        safe.)
752 *      - It is in practice very useful to have Box<T> be unconditionally
753 *        Unpin because of trait objects, for which the structural auto
754 *        trait functionality does not apply (e.g., Box<dyn Foo> would
755 *        otherwise not be Unpin).
756 *
757 *  Another type with the same semantics as Box but only a conditional
758 *  implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and
759 *  could have a method to project a Pin<T> from it.
760 */
761impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
762
763impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
764    type Target = T;
765
766    #[inline]
767    fn deref(&self) -> &T {
768        unsafe { self.ptr.as_ref() }
769    }
770}
771
772impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
773    #[inline]
774    fn deref_mut(&mut self) -> &mut T {
775        unsafe { self.ptr.as_mut() }
776    }
777}
778
779impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
780    #[inline]
781    fn drop(&mut self) {
782        unsafe {
783            let ptr = self.ptr;
784
785            if mem::needs_drop::<T>() {
786                ptr::drop_in_place(ptr.as_ptr());
787            }
788
789            let layout = for_value_raw(ptr.as_ptr());
790
791            if layout.size() != 0 {
792                self.alloc.deallocate(From::from(ptr.cast()), layout);
793            }
794        }
795    }
796}
797
798impl Default for Box<str, Global> {
799    fn default() -> Self {
800        // SAFETY: The layout of `Box<[u8]>` is the same as `Box<str>`.
801        unsafe {
802            let b = Box::<[u8]>::default();
803            let (ptr, alloc) = Box::into_raw_with_allocator(b);
804            Box::from_raw_in(ptr as *mut str, alloc)
805        }
806    }
807}
808
809impl<T> Default for Box<[T], Global> {
810    fn default() -> Self {
811        Box {
812            ptr: Unique::dangling_empty_slice(),
813            alloc: Global,
814        }
815    }
816}
817
818impl<T: ?Sized, A: Allocator> fmt::Display for Box<T, A>
819where
820    T: fmt::Display,
821{
822    #[inline]
823    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
824        (**self).fmt(f)
825    }
826}
827
828impl<T: ?Sized, A: Allocator> fmt::Debug for Box<T, A>
829where
830    T: fmt::Debug,
831{
832    #[inline]
833    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
834        (**self).fmt(f)
835    }
836}
837
838impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
839    fn from(value: Box<str, A>) -> Self {
840        // SAFETY: `[u8]` is layout compatible with `str` and there are no
841        // checks needed.
842        unsafe {
843            let (ptr, alloc) = Box::into_raw_with_allocator(value);
844            Box::from_raw_in(ptr as *mut [u8], alloc)
845        }
846    }
847}
848
849#[cfg(feature = "alloc")]
850impl<T> TryFrom<::rust_alloc::boxed::Box<[T]>> for Box<[T]> {
851    type Error = Error;
852
853    #[inline]
854    fn try_from(values: ::rust_alloc::boxed::Box<[T]>) -> Result<Self, Error> {
855        let mut vec = Vec::try_with_capacity(values.len())?;
856
857        for value in ::rust_alloc::vec::Vec::from(values) {
858            vec.try_push(value)?;
859        }
860
861        vec.try_into_boxed_slice()
862    }
863}
864
865impl<T, const N: usize> TryFrom<[T; N]> for Box<[T]> {
866    type Error = Error;
867
868    #[inline]
869    fn try_from(values: [T; N]) -> Result<Self, Error> {
870        let mut vec = Vec::try_with_capacity(values.len())?;
871
872        for value in values {
873            vec.try_push(value)?;
874        }
875
876        vec.try_into_boxed_slice()
877    }
878}
879
880/// Casts a boxed slice to a boxed array.
881///
882/// # Safety
883///
884/// `boxed_slice.len()` must be exactly `N`.
885unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
886    boxed_slice: Box<[T], A>,
887) -> Box<[T; N], A> {
888    debug_assert_eq!(boxed_slice.len(), N);
889
890    let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
891    // SAFETY: Pointer and allocator came from an existing box,
892    // and our safety condition requires that the length is exactly `N`
893    unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) }
894}
895
896impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
897    type Error = Box<[T]>;
898
899    /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
900    ///
901    /// The conversion occurs in-place and does not require a
902    /// new memory allocation.
903    ///
904    /// # Errors
905    ///
906    /// Returns the old `Box<[T]>` in the `Err` variant if
907    /// `boxed_slice.len()` does not equal `N`.
908    fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
909        if boxed_slice.len() == N {
910            Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
911        } else {
912            Err(boxed_slice)
913        }
914    }
915}
916
917impl<T, A: Allocator> TryFrom<Vec<T, A>> for Box<[T], A> {
918    type Error = Error;
919
920    #[inline]
921    fn try_from(vec: Vec<T, A>) -> Result<Self, Error> {
922        vec.try_into_boxed_slice()
923    }
924}
925
926impl<A: Allocator> Box<[u8], A> {
927    pub(crate) fn try_from_bytes_in(bytes: &[u8], alloc: A) -> Result<Self, Error> {
928        let mut vec = Vec::<u8, A>::try_with_capacity_in(bytes.len(), alloc)?;
929
930        unsafe {
931            ptr::copy_nonoverlapping(bytes.as_ptr(), vec.as_mut_ptr(), bytes.len());
932            vec.set_len(bytes.len());
933            vec.try_into_boxed_slice()
934        }
935    }
936}
937
938impl<A: Allocator> Box<str, A> {
939    pub(crate) fn try_from_string_in(string: &str, alloc: A) -> Result<Self, Error> {
940        unsafe {
941            let b = Box::try_from_bytes_in(string.as_bytes(), alloc)?;
942            let (raw, alloc) = Box::into_raw_with_allocator(b);
943            Ok(Box::from_raw_in(raw as *mut str, alloc))
944        }
945    }
946}
947
948impl<A: Allocator> Box<Path, A> {
949    pub(crate) fn try_from_path_in(path: &Path, alloc: A) -> Result<Self, Error> {
950        unsafe {
951            const _: () = assert!(mem::size_of::<&Path>() == mem::size_of::<&[u8]>());
952            // Replace with path.as_os_str().as_encoded_bytes() once that is
953            // stable.
954            let bytes = &*(path as *const _ as *const [u8]);
955            let b = Box::try_from_bytes_in(bytes, alloc)?;
956            let (raw, alloc) = Box::into_raw_with_allocator(b);
957            Ok(Box::from_raw_in(raw as *mut Path, alloc))
958        }
959    }
960}
961
962impl<A: Allocator + Clone> TryClone for Box<Path, A> {
963    #[inline]
964    fn try_clone(&self) -> Result<Self, Error> {
965        let alloc = self.alloc.clone();
966        Box::try_from_path_in(self.as_ref(), alloc)
967    }
968}
969
970impl TryFrom<&str> for Box<str> {
971    type Error = Error;
972
973    /// Converts a `&str` into a `Box<str>`.
974    ///
975    /// # Examples
976    ///
977    /// ```
978    /// use rune::alloc::Box;
979    ///
980    /// let s: Box<str> = Box::try_from("Hello World")?;
981    /// assert_eq!(s.as_ref(), "Hello World");
982    /// # Ok::<_, rune::alloc::Error>(())
983    /// ```
984    #[inline]
985    fn try_from(values: &str) -> Result<Self, Error> {
986        Box::try_from_string_in(values, Global)
987    }
988}
989
990#[cfg(feature = "alloc")]
991impl TryFrom<::rust_alloc::string::String> for Box<str> {
992    type Error = Error;
993
994    /// Converts a std `String` into a `Box<str>`.
995    ///
996    /// # Examples
997    ///
998    /// ```
999    /// use rune::alloc::Box;
1000    ///
1001    /// let s = String::from("Hello World");
1002    /// let s: Box<str> = Box::try_from(s)?;
1003    /// assert_eq!(s.as_ref(), "Hello World");
1004    /// # Ok::<_, rune::alloc::Error>(())
1005    /// ```
1006    #[inline]
1007    fn try_from(string: ::rust_alloc::string::String) -> Result<Self, Error> {
1008        Box::from_std(string.into_boxed_str())
1009    }
1010}
1011
1012impl TryFrom<&[u8]> for Box<[u8]> {
1013    type Error = Error;
1014
1015    /// Converts a `&[u8]` into a `Box<[u8]>`.
1016    ///
1017    /// # Examples
1018    ///
1019    /// ```
1020    /// use rune::alloc::Box;
1021    ///
1022    /// let s: Box<[u8]> = Box::try_from(&b"Hello World"[..])?;
1023    /// assert_eq!(s.as_ref(), b"Hello World");
1024    /// # Ok::<_, rune::alloc::Error>(())
1025    /// ```
1026    #[inline]
1027    fn try_from(values: &[u8]) -> Result<Self, Error> {
1028        Box::try_from_bytes_in(values, Global)
1029    }
1030}
1031
1032impl TryFrom<&Path> for Box<Path> {
1033    type Error = Error;
1034
1035    /// Converts a `&[u8]` into a `Box<[u8]>`.
1036    ///
1037    /// # Examples
1038    ///
1039    /// ```
1040    /// use std::path::Path;
1041    /// use rune::alloc::Box;
1042    ///
1043    /// let path = Path::new("foo/bar");
1044    ///
1045    /// let s: Box<Path> = Box::try_from(path)?;
1046    /// assert_eq!(s.as_ref(), Path::new("foo/bar"));
1047    /// # Ok::<_, rune::alloc::Error>(())
1048    /// ```
1049    #[inline]
1050    fn try_from(path: &Path) -> Result<Self, Error> {
1051        Box::try_from_path_in(path, Global)
1052    }
1053}
1054
1055impl<T, A: Allocator> TryFromIteratorIn<T, A> for Box<[T], A> {
1056    fn try_from_iter_in<I>(iter: I, alloc: A) -> Result<Self, Error>
1057    where
1058        I: IntoIterator<Item = T>,
1059    {
1060        Vec::<T, A>::try_from_iter_in(iter, alloc)?.try_into_boxed_slice()
1061    }
1062}
1063
1064unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Layout {
1065    // SAFETY: we pass along the prerequisites of these functions to the caller
1066    // TODO: Use mem::{size_of_val_raw, align_of_val_raw} when they become
1067    // stable, for now we privately know that this can safely be turned into a
1068    // reference since it's only used while dropping an owned value of type `T`.
1069    let (size, align) = (mem::size_of_val(&*t), mem::align_of_val(&*t));
1070    // SAFETY: see rationale in `new` for why this is using the unsafe variant
1071    Layout::from_size_align_unchecked(size, align)
1072}
1073
1074impl<T: ?Sized, A: Allocator> Hash for Box<T, A>
1075where
1076    T: Hash,
1077{
1078    #[inline]
1079    fn hash<H: Hasher>(&self, state: &mut H) {
1080        (**self).hash(state);
1081    }
1082}
1083
1084impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
1085where
1086    A: 'static,
1087{
1088    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement
1089    /// [`Unpin`], then `*boxed` will be pinned in memory and unable to be
1090    /// moved.
1091    ///
1092    /// This conversion does not allocate on the heap and happens in place.
1093    ///
1094    /// This is also available via [`Box::into_pin`].
1095    ///
1096    /// Constructing and pinning a `Box` with
1097    /// <code><Pin<Box\<T>>>::from([Box::try?new]\(x))</code> can also be
1098    /// written more concisely using <code>[Box::try?pin]\(x)</code>. This
1099    /// `From` implementation is useful if you already have a `Box<T>`, or you
1100    /// are constructing a (pinned) `Box` in a different way than with
1101    /// [`Box::try_new`].
1102    fn from(boxed: Box<T, A>) -> Self {
1103        Box::into_pin(boxed)
1104    }
1105}
1106
1107impl<T: ?Sized, A: Allocator> PartialEq for Box<T, A>
1108where
1109    T: PartialEq,
1110{
1111    #[inline]
1112    fn eq(&self, other: &Self) -> bool {
1113        (**self).eq(other)
1114    }
1115}
1116
1117impl<T: ?Sized, A: Allocator> Eq for Box<T, A> where T: Eq {}
1118
1119impl<T: ?Sized, A: Allocator> PartialOrd for Box<T, A>
1120where
1121    T: PartialOrd,
1122{
1123    #[inline]
1124    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1125        (**self).partial_cmp(other)
1126    }
1127}
1128
1129impl<T: ?Sized, A: Allocator> Ord for Box<T, A>
1130where
1131    T: Ord,
1132{
1133    #[inline]
1134    fn cmp(&self, other: &Self) -> Ordering {
1135        (**self).cmp(other)
1136    }
1137}