bevy_ptr/
lib.rs

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