allocator_api2/stable/
mod.rs

1#![deny(unsafe_op_in_unsafe_fn)]
2#![allow(clippy::needless_doctest_main, clippy::partialeq_ne_impl)]
3
4#[cfg(feature = "alloc")]
5pub use self::slice::SliceExt;
6
7pub mod alloc;
8
9#[cfg(feature = "alloc")]
10pub mod boxed;
11
12#[cfg(feature = "alloc")]
13mod raw_vec;
14
15#[cfg(feature = "alloc")]
16pub mod vec;
17
18#[cfg(feature = "alloc")]
19mod macros;
20
21#[cfg(feature = "alloc")]
22mod slice;
23
24#[cfg(feature = "alloc")]
25mod unique;
26
27/// Allows turning a [`Box<T: Sized, A>`][boxed::Box] into a [`Box<U: ?Sized, A>`][boxed::Box] where `T` can be unsizing-coerced into a `U`.
28///
29/// This is the only way to create an `allocator_api2::boxed::Box` of an unsized type on stable.
30///
31/// With the standard library's `alloc::boxed::Box`, this is done automatically using the unstable unsize traits, but this crate's Box
32/// can't take advantage of that machinery on stable. So, we need to use type inference and the fact that you *can*
33/// still coerce the inner pointer of a box to get the compiler to help us unsize it using this macro.
34///
35/// # Example
36///
37/// ```
38/// use allocator_api2::unsize_box;
39/// use allocator_api2::boxed::Box;
40/// use core::any::Any;
41///
42/// let sized_box: Box<u64> = Box::new(0);
43/// let unsized_box: Box<dyn Any> = unsize_box!(sized_box);
44/// ```
45#[macro_export]
46#[cfg(feature = "alloc")]
47macro_rules! unsize_box {( $boxed:expr $(,)? ) => ({
48    let (ptr, allocator) = ::allocator_api2::boxed::Box::into_raw_with_allocator($boxed);
49    // we don't want to allow casting to arbitrary type U, but we do want to allow unsize coercion to happen.
50    // that's exactly what's happening here -- this is *not* a pointer cast ptr as *mut _, but the compiler
51    // *will* allow an unsizing coercion to happen into the `ptr` place, if one is available. And we use _ so that the user can
52    // fill in what they want the unsized type to be by annotating the type of the variable this macro will
53    // assign its result to.
54    let ptr: *mut _ = ptr;
55    // SAFETY: see above for why ptr's type can only be something that can be safely coerced.
56    // also, ptr just came from a properly allocated box in the same allocator.
57    unsafe {
58        ::allocator_api2::boxed::Box::from_raw_in(ptr, allocator)
59    }
60})}
61
62#[cfg(feature = "alloc")]
63pub mod collections {
64    pub use super::raw_vec::{TryReserveError, TryReserveErrorKind};
65}
66
67#[cfg(feature = "alloc")]
68#[track_caller]
69#[inline(always)]
70#[cfg(debug_assertions)]
71unsafe fn assume(v: bool) {
72    if !v {
73        core::unreachable!()
74    }
75}
76
77#[cfg(feature = "alloc")]
78#[track_caller]
79#[inline(always)]
80#[cfg(not(debug_assertions))]
81unsafe fn assume(v: bool) {
82    if !v {
83        unsafe {
84            core::hint::unreachable_unchecked();
85        }
86    }
87}
88
89#[cfg(feature = "alloc")]
90#[inline(always)]
91fn addr<T>(x: *const T) -> usize {
92    #[allow(clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
93    unsafe {
94        core::mem::transmute(x)
95    }
96}
97
98#[cfg(feature = "alloc")]
99#[inline(always)]
100fn invalid_mut<T>(addr: usize) -> *mut T {
101    #[allow(clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
102    unsafe {
103        core::mem::transmute(addr)
104    }
105}