bevy_ptr/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4#![allow(unsafe_code)]
5#![doc(
6    html_logo_url = "https://bevyengine.org/assets/icon.png",
7    html_favicon_url = "https://bevyengine.org/assets/icon.png"
8)]
9
10use core::fmt::{self, Formatter, Pointer};
11use core::{
12    cell::UnsafeCell, marker::PhantomData, mem::ManuallyDrop, num::NonZeroUsize, ptr::NonNull,
13};
14
15/// Used as a type argument to [`Ptr`], [`PtrMut`] and [`OwningPtr`] to specify that the pointer is aligned.
16#[derive(Copy, Clone)]
17pub struct Aligned;
18
19/// Used as a type argument to [`Ptr`], [`PtrMut`] and [`OwningPtr`] to specify that the pointer is not aligned.
20#[derive(Copy, Clone)]
21pub struct Unaligned;
22
23/// Trait that is only implemented for [`Aligned`] and [`Unaligned`] to work around the lack of ability
24/// to have const generics of an enum.
25pub trait IsAligned: sealed::Sealed {}
26impl IsAligned for Aligned {}
27impl IsAligned for Unaligned {}
28
29mod sealed {
30    pub trait Sealed {}
31    impl Sealed for super::Aligned {}
32    impl Sealed for super::Unaligned {}
33}
34
35/// A newtype around [`NonNull`] that only allows conversion to read-only borrows or pointers.
36///
37/// This type can be thought of as the `*const T` to [`NonNull<T>`]'s `*mut T`.
38#[repr(transparent)]
39pub struct ConstNonNull<T: ?Sized>(NonNull<T>);
40
41impl<T: ?Sized> ConstNonNull<T> {
42    /// Creates a new `ConstNonNull` if `ptr` is non-null.
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// use bevy_ptr::ConstNonNull;
48    ///
49    /// let x = 0u32;
50    /// let ptr = ConstNonNull::<u32>::new(&x as *const _).expect("ptr is null!");
51    ///
52    /// if let Some(ptr) = ConstNonNull::<u32>::new(std::ptr::null()) {
53    ///     unreachable!();
54    /// }
55    /// ```
56    pub fn new(ptr: *const T) -> Option<Self> {
57        NonNull::new(ptr.cast_mut()).map(Self)
58    }
59
60    /// Creates a new `ConstNonNull`.
61    ///
62    /// # Safety
63    ///
64    /// `ptr` must be non-null.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use bevy_ptr::ConstNonNull;
70    ///
71    /// let x = 0u32;
72    /// let ptr = unsafe { ConstNonNull::new_unchecked(&x as *const _) };
73    /// ```
74    ///
75    /// *Incorrect* usage of this function:
76    ///
77    /// ```rust,no_run
78    /// use bevy_ptr::ConstNonNull;
79    ///
80    /// // NEVER DO THAT!!! This is undefined behavior. ⚠️
81    /// let ptr = unsafe { ConstNonNull::<u32>::new_unchecked(std::ptr::null()) };
82    /// ```
83    pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
84        // SAFETY: This function's safety invariants are identical to `NonNull::new_unchecked`
85        // The caller must satisfy all of them.
86        unsafe { Self(NonNull::new_unchecked(ptr.cast_mut())) }
87    }
88
89    /// Returns a shared reference to the value.
90    ///
91    /// # Safety
92    ///
93    /// When calling this method, you have to ensure that all of the following is true:
94    ///
95    /// * The pointer must be properly aligned.
96    ///
97    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
98    ///
99    /// * The pointer must point to an initialized instance of `T`.
100    ///
101    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
102    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
103    ///   In particular, while this reference exists, the memory the pointer points to must
104    ///   not get mutated (except inside `UnsafeCell`).
105    ///
106    /// This applies even if the result of this method is unused!
107    /// (The part about being initialized is not yet fully decided, but until
108    /// it is, the only safe approach is to ensure that they are indeed initialized.)
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use bevy_ptr::ConstNonNull;
114    ///
115    /// let mut x = 0u32;
116    /// let ptr = ConstNonNull::new(&mut x as *mut _).expect("ptr is null!");
117    ///
118    /// let ref_x = unsafe { ptr.as_ref() };
119    /// println!("{ref_x}");
120    /// ```
121    ///
122    /// [the module documentation]: core::ptr#safety
123    #[inline]
124    pub unsafe fn as_ref<'a>(&self) -> &'a T {
125        // SAFETY: This function's safety invariants are identical to `NonNull::as_ref`
126        // The caller must satisfy all of them.
127        unsafe { self.0.as_ref() }
128    }
129}
130
131impl<T: ?Sized> From<NonNull<T>> for ConstNonNull<T> {
132    fn from(value: NonNull<T>) -> ConstNonNull<T> {
133        ConstNonNull(value)
134    }
135}
136
137impl<'a, T: ?Sized> From<&'a T> for ConstNonNull<T> {
138    fn from(value: &'a T) -> ConstNonNull<T> {
139        ConstNonNull(NonNull::from(value))
140    }
141}
142
143impl<'a, T: ?Sized> From<&'a mut T> for ConstNonNull<T> {
144    fn from(value: &'a mut T) -> ConstNonNull<T> {
145        ConstNonNull(NonNull::from(value))
146    }
147}
148/// Type-erased borrow of some unknown type chosen when constructing this type.
149///
150/// This type tries to act "borrow-like" which means that:
151/// - It should be considered immutable: its target must not be changed while this pointer is alive.
152/// - It must always points to a valid value of whatever the pointee type is.
153/// - The lifetime `'a` accurately represents how long the pointer is valid for.
154/// - Must be sufficiently aligned for the unknown pointee type.
155///
156/// It may be helpful to think of this type as similar to `&'a dyn Any` but without
157/// the metadata and able to point to data that does not correspond to a Rust type.
158#[derive(Copy, Clone, Debug)]
159#[repr(transparent)]
160pub struct Ptr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a u8, A)>);
161
162/// Type-erased mutable borrow of some unknown type chosen when constructing this type.
163///
164/// This type tries to act "borrow-like" which means that:
165/// - Pointer is considered exclusive and mutable. It cannot be cloned as this would lead to
166///   aliased mutability.
167/// - It must always points to a valid value of whatever the pointee type is.
168/// - The lifetime `'a` accurately represents how long the pointer is valid for.
169/// - Must be sufficiently aligned for the unknown pointee type.
170///
171/// It may be helpful to think of this type as similar to `&'a mut dyn Any` but without
172/// the metadata and able to point to data that does not correspond to a Rust type.
173#[derive(Debug)]
174#[repr(transparent)]
175pub struct PtrMut<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
176
177/// Type-erased Box-like pointer to some unknown type chosen when constructing this type.
178/// Conceptually represents ownership of whatever data is being pointed to and so is
179/// responsible for calling its `Drop` impl. This pointer is _not_ responsible for freeing
180/// the memory pointed to by this pointer as it may be pointing to an element in a `Vec` or
181/// to a local in a function etc.
182///
183/// This type tries to act "borrow-like" like which means that:
184/// - Pointer should be considered exclusive and mutable. It cannot be cloned as this would lead
185///   to aliased mutability and potentially use after free bugs.
186/// - It must always points to a valid value of whatever the pointee type is.
187/// - The lifetime `'a` accurately represents how long the pointer is valid for.
188/// - Must be sufficiently aligned for the unknown pointee type.
189///
190/// It may be helpful to think of this type as similar to `&'a mut ManuallyDrop<dyn Any>` but
191/// without the metadata and able to point to data that does not correspond to a Rust type.
192#[derive(Debug)]
193#[repr(transparent)]
194pub struct OwningPtr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
195
196macro_rules! impl_ptr {
197    ($ptr:ident) => {
198        impl<'a> $ptr<'a, Aligned> {
199            /// Removes the alignment requirement of this pointer
200            pub fn to_unaligned(self) -> $ptr<'a, Unaligned> {
201                $ptr(self.0, PhantomData)
202            }
203        }
204
205        impl<'a, A: IsAligned> From<$ptr<'a, A>> for NonNull<u8> {
206            fn from(ptr: $ptr<'a, A>) -> Self {
207                ptr.0
208            }
209        }
210
211        impl<A: IsAligned> $ptr<'_, A> {
212            /// Calculates the offset from a pointer.
213            /// As the pointer is type-erased, there is no size information available. The provided
214            /// `count` parameter is in raw bytes.
215            ///
216            /// *See also: [`ptr::offset`][ptr_offset]*
217            ///
218            /// # Safety
219            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
220            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
221            ///   be unaligned for the pointee type.
222            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
223            ///
224            /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
225            #[inline]
226            pub unsafe fn byte_offset(self, count: isize) -> Self {
227                Self(
228                    // SAFETY: The caller upholds safety for `offset` and ensures the result is not null.
229                    unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
230                    PhantomData,
231                )
232            }
233
234            /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
235            /// As the pointer is type-erased, there is no size information available. The provided
236            /// `count` parameter is in raw bytes.
237            ///
238            /// *See also: [`ptr::add`][ptr_add]*
239            ///
240            /// # Safety
241            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
242            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
243            ///   be unaligned for the pointee type.
244            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
245            ///
246            /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
247            #[inline]
248            pub unsafe fn byte_add(self, count: usize) -> Self {
249                Self(
250                    // SAFETY: The caller upholds safety for `add` and ensures the result is not null.
251                    unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
252                    PhantomData,
253                )
254            }
255        }
256
257        impl<A: IsAligned> Pointer for $ptr<'_, A> {
258            #[inline]
259            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
260                Pointer::fmt(&self.0, f)
261            }
262        }
263    };
264}
265
266impl_ptr!(Ptr);
267impl_ptr!(PtrMut);
268impl_ptr!(OwningPtr);
269
270impl<'a, A: IsAligned> Ptr<'a, A> {
271    /// Creates a new instance from a raw pointer.
272    ///
273    /// # Safety
274    /// - `inner` must point to valid value of whatever the pointee type is.
275    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
276    /// - `inner` must have correct provenance to allow reads of the pointee type.
277    /// - The lifetime `'a` must be constrained such that this [`Ptr`] will stay valid and nothing
278    ///   can mutate the pointee while this [`Ptr`] is live except through an [`UnsafeCell`].
279    #[inline]
280    pub unsafe fn new(inner: NonNull<u8>) -> Self {
281        Self(inner, PhantomData)
282    }
283
284    /// Transforms this [`Ptr`] into an [`PtrMut`]
285    ///
286    /// # Safety
287    /// Another [`PtrMut`] for the same [`Ptr`] must not be created until the first is dropped.
288    #[inline]
289    pub unsafe fn assert_unique(self) -> PtrMut<'a, A> {
290        PtrMut(self.0, PhantomData)
291    }
292
293    /// Transforms this [`Ptr<T>`] into a `&T` with the same lifetime
294    ///
295    /// # Safety
296    /// - `T` must be the erased pointee type for this [`Ptr`].
297    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
298    ///   for the pointee type `T`.
299    #[inline]
300    pub unsafe fn deref<T>(self) -> &'a T {
301        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
302        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
303        unsafe { &*ptr }
304    }
305
306    /// Gets the underlying pointer, erasing the associated lifetime.
307    ///
308    /// If possible, it is strongly encouraged to use [`deref`](Self::deref) over this function,
309    /// as it retains the lifetime.
310    #[inline]
311    #[allow(clippy::wrong_self_convention)]
312    pub fn as_ptr(self) -> *mut u8 {
313        self.0.as_ptr()
314    }
315}
316
317impl<'a, T> From<&'a T> for Ptr<'a> {
318    #[inline]
319    fn from(val: &'a T) -> Self {
320        // SAFETY: The returned pointer has the same lifetime as the passed reference.
321        // Access is immutable.
322        unsafe { Self::new(NonNull::from(val).cast()) }
323    }
324}
325
326impl<'a, A: IsAligned> PtrMut<'a, A> {
327    /// Creates a new instance from a raw pointer.
328    ///
329    /// # Safety
330    /// - `inner` must point to valid value of whatever the pointee type is.
331    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
332    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
333    /// - The lifetime `'a` must be constrained such that this [`PtrMut`] will stay valid and nothing
334    ///   else can read or mutate the pointee while this [`PtrMut`] is live.
335    #[inline]
336    pub unsafe fn new(inner: NonNull<u8>) -> Self {
337        Self(inner, PhantomData)
338    }
339
340    /// Transforms this [`PtrMut`] into an [`OwningPtr`]
341    ///
342    /// # Safety
343    /// Must have right to drop or move out of [`PtrMut`].
344    #[inline]
345    pub unsafe fn promote(self) -> OwningPtr<'a, A> {
346        OwningPtr(self.0, PhantomData)
347    }
348
349    /// Transforms this [`PtrMut<T>`] into a `&mut T` with the same lifetime
350    ///
351    /// # Safety
352    /// - `T` must be the erased pointee type for this [`PtrMut`].
353    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
354    ///   for the pointee type `T`.
355    #[inline]
356    pub unsafe fn deref_mut<T>(self) -> &'a mut T {
357        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
358        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
359        unsafe { &mut *ptr }
360    }
361
362    /// Gets the underlying pointer, erasing the associated lifetime.
363    ///
364    /// If possible, it is strongly encouraged to use [`deref_mut`](Self::deref_mut) over
365    /// this function, as it retains the lifetime.
366    #[inline]
367    #[allow(clippy::wrong_self_convention)]
368    pub fn as_ptr(&self) -> *mut u8 {
369        self.0.as_ptr()
370    }
371
372    /// Gets a [`PtrMut`] from this with a smaller lifetime.
373    #[inline]
374    pub fn reborrow(&mut self) -> PtrMut<'_, A> {
375        // SAFETY: the ptrmut we're borrowing from is assumed to be valid
376        unsafe { PtrMut::new(self.0) }
377    }
378
379    /// Gets an immutable reference from this mutable reference
380    #[inline]
381    pub fn as_ref(&self) -> Ptr<'_, A> {
382        // SAFETY: The `PtrMut` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
383        unsafe { Ptr::new(self.0) }
384    }
385}
386
387impl<'a, T> From<&'a mut T> for PtrMut<'a> {
388    #[inline]
389    fn from(val: &'a mut T) -> Self {
390        // SAFETY: The returned pointer has the same lifetime as the passed reference.
391        // The reference is mutable, and thus will not alias.
392        unsafe { Self::new(NonNull::from(val).cast()) }
393    }
394}
395
396impl<'a> OwningPtr<'a> {
397    /// Consumes a value and creates an [`OwningPtr`] to it while ensuring a double drop does not happen.
398    #[inline]
399    pub fn make<T, F: FnOnce(OwningPtr<'_>) -> R, R>(val: T, f: F) -> R {
400        let mut temp = ManuallyDrop::new(val);
401        // SAFETY: The value behind the pointer will not get dropped or observed later,
402        // so it's safe to promote it to an owning pointer.
403        f(unsafe { PtrMut::from(&mut *temp).promote() })
404    }
405}
406
407impl<'a, A: IsAligned> OwningPtr<'a, A> {
408    /// Creates a new instance from a raw pointer.
409    ///
410    /// # Safety
411    /// - `inner` must point to valid value of whatever the pointee type is.
412    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
413    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
414    /// - The lifetime `'a` must be constrained such that this [`OwningPtr`] will stay valid and nothing
415    ///   else can read or mutate the pointee while this [`OwningPtr`] is live.
416    #[inline]
417    pub unsafe fn new(inner: NonNull<u8>) -> Self {
418        Self(inner, PhantomData)
419    }
420
421    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
422    ///
423    /// # Safety
424    /// - `T` must be the erased pointee type for this [`OwningPtr`].
425    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
426    ///   for the pointee type `T`.
427    #[inline]
428    pub unsafe fn read<T>(self) -> T {
429        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
430        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
431        unsafe { ptr.read() }
432    }
433
434    /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
435    ///
436    /// # Safety
437    /// - `T` must be the erased pointee type for this [`OwningPtr`].
438    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
439    ///   for the pointee type `T`.
440    #[inline]
441    pub unsafe fn drop_as<T>(self) {
442        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
443        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
444        unsafe {
445            ptr.drop_in_place();
446        }
447    }
448
449    /// Gets the underlying pointer, erasing the associated lifetime.
450    ///
451    /// If possible, it is strongly encouraged to use the other more type-safe functions
452    /// over this function.
453    #[inline]
454    #[allow(clippy::wrong_self_convention)]
455    pub fn as_ptr(&self) -> *mut u8 {
456        self.0.as_ptr()
457    }
458
459    /// Gets an immutable pointer from this owned pointer.
460    #[inline]
461    pub fn as_ref(&self) -> Ptr<'_, A> {
462        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
463        unsafe { Ptr::new(self.0) }
464    }
465
466    /// Gets a mutable pointer from this owned pointer.
467    #[inline]
468    pub fn as_mut(&mut self) -> PtrMut<'_, A> {
469        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
470        unsafe { PtrMut::new(self.0) }
471    }
472}
473
474impl<'a> OwningPtr<'a, Unaligned> {
475    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
476    ///
477    /// # Safety
478    /// - `T` must be the erased pointee type for this [`OwningPtr`].
479    pub unsafe fn read_unaligned<T>(self) -> T {
480        let ptr = self.as_ptr().cast::<T>();
481        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
482        unsafe { ptr.read_unaligned() }
483    }
484}
485
486/// Conceptually equivalent to `&'a [T]` but with length information cut out for performance reasons
487pub struct ThinSlicePtr<'a, T> {
488    ptr: NonNull<T>,
489    #[cfg(debug_assertions)]
490    len: usize,
491    _marker: PhantomData<&'a [T]>,
492}
493
494impl<'a, T> ThinSlicePtr<'a, T> {
495    #[inline]
496    /// Indexes the slice without doing bounds checks
497    ///
498    /// # Safety
499    /// `index` must be in-bounds.
500    pub unsafe fn get(self, index: usize) -> &'a T {
501        #[cfg(debug_assertions)]
502        debug_assert!(index < self.len);
503
504        let ptr = self.ptr.as_ptr();
505        // SAFETY: `index` is in-bounds so the resulting pointer is valid to dereference.
506        unsafe { &*ptr.add(index) }
507    }
508}
509
510impl<'a, T> Clone for ThinSlicePtr<'a, T> {
511    fn clone(&self) -> Self {
512        *self
513    }
514}
515
516impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
517
518impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
519    #[inline]
520    fn from(slice: &'a [T]) -> Self {
521        let ptr = slice.as_ptr().cast_mut();
522        Self {
523            // SAFETY: a reference can never be null
524            ptr: unsafe { NonNull::new_unchecked(ptr.debug_ensure_aligned()) },
525            #[cfg(debug_assertions)]
526            len: slice.len(),
527            _marker: PhantomData,
528        }
529    }
530}
531
532/// Creates a dangling pointer with specified alignment.
533/// See [`NonNull::dangling`].
534pub fn dangling_with_align(align: NonZeroUsize) -> NonNull<u8> {
535    debug_assert!(align.is_power_of_two(), "Alignment must be power of two.");
536    // SAFETY: The pointer will not be null, since it was created
537    // from the address of a `NonZeroUsize`.
538    unsafe { NonNull::new_unchecked(align.get() as *mut u8) }
539}
540
541mod private {
542    use core::cell::UnsafeCell;
543
544    pub trait SealedUnsafeCell {}
545    impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
546}
547
548/// Extension trait for helper methods on [`UnsafeCell`]
549pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
550    /// # Safety
551    /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
552    /// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
553    unsafe fn deref_mut(self) -> &'a mut T;
554
555    /// # Safety
556    /// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
557    /// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
558    unsafe fn deref(self) -> &'a T;
559
560    /// Returns a copy of the contained value.
561    ///
562    /// # Safety
563    /// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
564    /// - At all times, you must avoid data races. If multiple threads have access to the same [`UnsafeCell`], then any writes must have a proper happens-before relation to all other accesses or use atomics ([`UnsafeCell`] docs for reference).
565    unsafe fn read(self) -> T
566    where
567        T: Copy;
568}
569
570impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
571    #[inline]
572    unsafe fn deref_mut(self) -> &'a mut T {
573        // SAFETY: The caller upholds the alias rules.
574        unsafe { &mut *self.get() }
575    }
576    #[inline]
577    unsafe fn deref(self) -> &'a T {
578        // SAFETY: The caller upholds the alias rules.
579        unsafe { &*self.get() }
580    }
581
582    #[inline]
583    unsafe fn read(self) -> T
584    where
585        T: Copy,
586    {
587        // SAFETY: The caller upholds the alias rules.
588        unsafe { self.get().read() }
589    }
590}
591
592trait DebugEnsureAligned {
593    fn debug_ensure_aligned(self) -> Self;
594}
595
596// Disable this for miri runs as it already checks if pointer to reference
597// casts are properly aligned.
598#[cfg(all(debug_assertions, not(miri)))]
599impl<T: Sized> DebugEnsureAligned for *mut T {
600    #[track_caller]
601    fn debug_ensure_aligned(self) -> Self {
602        let align = core::mem::align_of::<T>();
603        // Implementation shamelessly borrowed from the currently unstable
604        // ptr.is_aligned_to.
605        //
606        // Replace once https://github.com/rust-lang/rust/issues/96284 is stable.
607        assert_eq!(
608            self as usize & (align - 1),
609            0,
610            "pointer is not aligned. Address {:p} does not have alignment {} for type {}",
611            self,
612            align,
613            core::any::type_name::<T>()
614        );
615        self
616    }
617}
618
619#[cfg(any(not(debug_assertions), miri))]
620impl<T: Sized> DebugEnsureAligned for *mut T {
621    #[inline(always)]
622    fn debug_ensure_aligned(self) -> Self {
623        self
624    }
625}