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, Debug, 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(Debug, 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(Debug, 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)]
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#[repr(transparent)]
178pub struct PtrMut<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
179
180/// Type-erased Box-like pointer to some unknown type chosen when constructing this type.
181///
182/// Conceptually represents ownership of whatever data is being pointed to and so is
183/// responsible for calling its `Drop` impl. This pointer is _not_ responsible for freeing
184/// the memory pointed to by this pointer as it may be pointing to an element in a `Vec` or
185/// to a local in a function etc.
186///
187/// This type tries to act "borrow-like" like which means that:
188/// - Pointer should be considered exclusive and mutable. It cannot be cloned as this would lead
189///   to aliased mutability and potentially use after free bugs.
190/// - It must always points to a valid value of whatever the pointee type is.
191/// - The lifetime `'a` accurately represents how long the pointer is valid for.
192/// - Must be sufficiently aligned for the unknown pointee type.
193///
194/// It may be helpful to think of this type as similar to `&'a mut ManuallyDrop<dyn Any>` but
195/// without the metadata and able to point to data that does not correspond to a Rust type.
196#[repr(transparent)]
197pub struct OwningPtr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
198
199macro_rules! impl_ptr {
200    ($ptr:ident) => {
201        impl<'a> $ptr<'a, Aligned> {
202            /// Removes the alignment requirement of this pointer
203            pub fn to_unaligned(self) -> $ptr<'a, Unaligned> {
204                $ptr(self.0, PhantomData)
205            }
206        }
207
208        impl<'a, A: IsAligned> From<$ptr<'a, A>> for NonNull<u8> {
209            fn from(ptr: $ptr<'a, A>) -> Self {
210                ptr.0
211            }
212        }
213
214        impl<A: IsAligned> $ptr<'_, A> {
215            /// Calculates the offset from a pointer.
216            /// As the pointer is type-erased, there is no size information available. The provided
217            /// `count` parameter is in raw bytes.
218            ///
219            /// *See also: [`ptr::offset`][ptr_offset]*
220            ///
221            /// # Safety
222            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
223            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
224            ///   be unaligned for the pointee type.
225            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
226            ///
227            /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
228            #[inline]
229            pub unsafe fn byte_offset(self, count: isize) -> Self {
230                Self(
231                    // SAFETY: The caller upholds safety for `offset` and ensures the result is not null.
232                    unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
233                    PhantomData,
234                )
235            }
236
237            /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
238            /// As the pointer is type-erased, there is no size information available. The provided
239            /// `count` parameter is in raw bytes.
240            ///
241            /// *See also: [`ptr::add`][ptr_add]*
242            ///
243            /// # Safety
244            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
245            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
246            ///   be unaligned for the pointee type.
247            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
248            ///
249            /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
250            #[inline]
251            pub unsafe fn byte_add(self, count: usize) -> Self {
252                Self(
253                    // SAFETY: The caller upholds safety for `add` and ensures the result is not null.
254                    unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
255                    PhantomData,
256                )
257            }
258        }
259
260        impl<A: IsAligned> Pointer for $ptr<'_, A> {
261            #[inline]
262            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
263                Pointer::fmt(&self.0, f)
264            }
265        }
266
267        impl Debug for $ptr<'_, Aligned> {
268            #[inline]
269            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
270                write!(f, "{}<Aligned>({:?})", stringify!($ptr), self.0)
271            }
272        }
273        impl Debug for $ptr<'_, Unaligned> {
274            #[inline]
275            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
276                write!(f, "{}<Unaligned>({:?})", stringify!($ptr), self.0)
277            }
278        }
279    };
280}
281
282impl_ptr!(Ptr);
283impl_ptr!(PtrMut);
284impl_ptr!(OwningPtr);
285
286impl<'a, A: IsAligned> Ptr<'a, A> {
287    /// Creates a new instance from a raw pointer.
288    ///
289    /// # Safety
290    /// - `inner` must point to valid value of whatever the pointee type is.
291    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
292    /// - `inner` must have correct provenance to allow reads of the pointee type.
293    /// - The lifetime `'a` must be constrained such that this [`Ptr`] will stay valid and nothing
294    ///   can mutate the pointee while this [`Ptr`] is live except through an [`UnsafeCell`].
295    #[inline]
296    pub unsafe fn new(inner: NonNull<u8>) -> Self {
297        Self(inner, PhantomData)
298    }
299
300    /// Transforms this [`Ptr`] into an [`PtrMut`]
301    ///
302    /// # Safety
303    /// * The data pointed to by this `Ptr` must be valid for writes.
304    /// * There must be no active references (mutable or otherwise) to the data underlying this `Ptr`.
305    /// * Another [`PtrMut`] for the same [`Ptr`] must not be created until the first is dropped.
306    #[inline]
307    pub unsafe fn assert_unique(self) -> PtrMut<'a, A> {
308        PtrMut(self.0, PhantomData)
309    }
310
311    /// Transforms this [`Ptr<T>`] into a `&T` with the same lifetime
312    ///
313    /// # Safety
314    /// - `T` must be the erased pointee type for this [`Ptr`].
315    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
316    ///   for the pointee type `T`.
317    #[inline]
318    pub unsafe fn deref<T>(self) -> &'a T {
319        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
320        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
321        unsafe { &*ptr }
322    }
323
324    /// Gets the underlying pointer, erasing the associated lifetime.
325    ///
326    /// If possible, it is strongly encouraged to use [`deref`](Self::deref) over this function,
327    /// as it retains the lifetime.
328    #[inline]
329    pub fn as_ptr(self) -> *mut u8 {
330        self.0.as_ptr()
331    }
332}
333
334impl<'a, T: ?Sized> From<&'a T> for Ptr<'a> {
335    #[inline]
336    fn from(val: &'a T) -> Self {
337        // SAFETY: The returned pointer has the same lifetime as the passed reference.
338        // Access is immutable.
339        unsafe { Self::new(NonNull::from(val).cast()) }
340    }
341}
342
343impl<'a, A: IsAligned> PtrMut<'a, A> {
344    /// Creates a new instance from a raw pointer.
345    ///
346    /// # Safety
347    /// - `inner` must point to valid value of whatever the pointee type is.
348    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
349    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
350    /// - The lifetime `'a` must be constrained such that this [`PtrMut`] will stay valid and nothing
351    ///   else can read or mutate the pointee while this [`PtrMut`] is live.
352    #[inline]
353    pub unsafe fn new(inner: NonNull<u8>) -> Self {
354        Self(inner, PhantomData)
355    }
356
357    /// Transforms this [`PtrMut`] into an [`OwningPtr`]
358    ///
359    /// # Safety
360    /// Must have right to drop or move out of [`PtrMut`].
361    #[inline]
362    pub unsafe fn promote(self) -> OwningPtr<'a, A> {
363        OwningPtr(self.0, PhantomData)
364    }
365
366    /// Transforms this [`PtrMut<T>`] into a `&mut T` with the same lifetime
367    ///
368    /// # Safety
369    /// - `T` must be the erased pointee type for this [`PtrMut`].
370    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
371    ///   for the pointee type `T`.
372    #[inline]
373    pub unsafe fn deref_mut<T>(self) -> &'a mut T {
374        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
375        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
376        unsafe { &mut *ptr }
377    }
378
379    /// Gets the underlying pointer, erasing the associated lifetime.
380    ///
381    /// If possible, it is strongly encouraged to use [`deref_mut`](Self::deref_mut) over
382    /// this function, as it retains the lifetime.
383    #[inline]
384    pub fn as_ptr(&self) -> *mut u8 {
385        self.0.as_ptr()
386    }
387
388    /// Gets a [`PtrMut`] from this with a smaller lifetime.
389    #[inline]
390    pub fn reborrow(&mut self) -> PtrMut<'_, A> {
391        // SAFETY: the ptrmut we're borrowing from is assumed to be valid
392        unsafe { PtrMut::new(self.0) }
393    }
394
395    /// Gets an immutable reference from this mutable reference
396    #[inline]
397    pub fn as_ref(&self) -> Ptr<'_, A> {
398        // SAFETY: The `PtrMut` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
399        unsafe { Ptr::new(self.0) }
400    }
401}
402
403impl<'a, T: ?Sized> From<&'a mut T> for PtrMut<'a> {
404    #[inline]
405    fn from(val: &'a mut T) -> Self {
406        // SAFETY: The returned pointer has the same lifetime as the passed reference.
407        // The reference is mutable, and thus will not alias.
408        unsafe { Self::new(NonNull::from(val).cast()) }
409    }
410}
411
412impl<'a> OwningPtr<'a> {
413    /// This exists mostly to reduce compile times;
414    /// code is only duplicated per type, rather than per function called.
415    ///
416    /// # Safety
417    ///
418    /// Safety constraints of [`PtrMut::promote`] must be upheld.
419    unsafe fn make_internal<T>(temp: &mut ManuallyDrop<T>) -> OwningPtr<'_> {
420        // SAFETY: The constraints of `promote` are upheld by caller.
421        unsafe { PtrMut::from(&mut *temp).promote() }
422    }
423
424    /// Consumes a value and creates an [`OwningPtr`] to it while ensuring a double drop does not happen.
425    #[inline]
426    pub fn make<T, F: FnOnce(OwningPtr<'_>) -> R, R>(val: T, f: F) -> R {
427        let mut val = ManuallyDrop::new(val);
428        // SAFETY: The value behind the pointer will not get dropped or observed later,
429        // so it's safe to promote it to an owning pointer.
430        f(unsafe { Self::make_internal(&mut val) })
431    }
432}
433
434impl<'a, A: IsAligned> OwningPtr<'a, A> {
435    /// Creates a new instance from a raw pointer.
436    ///
437    /// # Safety
438    /// - `inner` must point to valid value of whatever the pointee type is.
439    /// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
440    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
441    /// - The lifetime `'a` must be constrained such that this [`OwningPtr`] will stay valid and nothing
442    ///   else can read or mutate the pointee while this [`OwningPtr`] is live.
443    #[inline]
444    pub unsafe fn new(inner: NonNull<u8>) -> Self {
445        Self(inner, PhantomData)
446    }
447
448    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
449    ///
450    /// # Safety
451    /// - `T` must be the erased pointee type for this [`OwningPtr`].
452    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
453    ///   for the pointee type `T`.
454    #[inline]
455    pub unsafe fn read<T>(self) -> T {
456        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
457        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
458        unsafe { ptr.read() }
459    }
460
461    /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
462    ///
463    /// # Safety
464    /// - `T` must be the erased pointee type for this [`OwningPtr`].
465    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
466    ///   for the pointee type `T`.
467    #[inline]
468    pub unsafe fn drop_as<T>(self) {
469        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
470        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
471        unsafe {
472            ptr.drop_in_place();
473        }
474    }
475
476    /// Gets the underlying pointer, erasing the associated lifetime.
477    ///
478    /// If possible, it is strongly encouraged to use the other more type-safe functions
479    /// over this function.
480    #[inline]
481    pub fn as_ptr(&self) -> *mut u8 {
482        self.0.as_ptr()
483    }
484
485    /// Gets an immutable pointer from this owned pointer.
486    #[inline]
487    pub fn as_ref(&self) -> Ptr<'_, A> {
488        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
489        unsafe { Ptr::new(self.0) }
490    }
491
492    /// Gets a mutable pointer from this owned pointer.
493    #[inline]
494    pub fn as_mut(&mut self) -> PtrMut<'_, A> {
495        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
496        unsafe { PtrMut::new(self.0) }
497    }
498}
499
500impl<'a> OwningPtr<'a, Unaligned> {
501    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
502    ///
503    /// # Safety
504    /// - `T` must be the erased pointee type for this [`OwningPtr`].
505    pub unsafe fn read_unaligned<T>(self) -> T {
506        let ptr = self.as_ptr().cast::<T>();
507        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
508        unsafe { ptr.read_unaligned() }
509    }
510}
511
512/// Conceptually equivalent to `&'a [T]` but with length information cut out for performance reasons
513pub struct ThinSlicePtr<'a, T> {
514    ptr: NonNull<T>,
515    #[cfg(debug_assertions)]
516    len: usize,
517    _marker: PhantomData<&'a [T]>,
518}
519
520impl<'a, T> ThinSlicePtr<'a, T> {
521    #[inline]
522    /// Indexes the slice without doing bounds checks
523    ///
524    /// # Safety
525    /// `index` must be in-bounds.
526    pub unsafe fn get(self, index: usize) -> &'a T {
527        #[cfg(debug_assertions)]
528        debug_assert!(index < self.len);
529
530        let ptr = self.ptr.as_ptr();
531        // SAFETY: `index` is in-bounds so the resulting pointer is valid to dereference.
532        unsafe { &*ptr.add(index) }
533    }
534}
535
536impl<'a, T> Clone for ThinSlicePtr<'a, T> {
537    fn clone(&self) -> Self {
538        *self
539    }
540}
541
542impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
543
544impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
545    #[inline]
546    fn from(slice: &'a [T]) -> Self {
547        let ptr = slice.as_ptr().cast_mut();
548        Self {
549            // SAFETY: a reference can never be null
550            ptr: unsafe { NonNull::new_unchecked(ptr.debug_ensure_aligned()) },
551            #[cfg(debug_assertions)]
552            len: slice.len(),
553            _marker: PhantomData,
554        }
555    }
556}
557
558/// Creates a dangling pointer with specified alignment.
559/// See [`NonNull::dangling`].
560pub const fn dangling_with_align(align: NonZeroUsize) -> NonNull<u8> {
561    debug_assert!(align.is_power_of_two(), "Alignment must be power of two.");
562    // SAFETY: The pointer will not be null, since it was created
563    // from the address of a `NonZero<usize>`.
564    // TODO: use https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.with_addr once stabilized
565    unsafe { NonNull::new_unchecked(ptr::null_mut::<u8>().wrapping_add(align.get())) }
566}
567
568mod private {
569    use core::cell::UnsafeCell;
570
571    pub trait SealedUnsafeCell {}
572    impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
573}
574
575/// Extension trait for helper methods on [`UnsafeCell`]
576pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
577    /// # Safety
578    /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
579    /// - 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).
580    unsafe fn deref_mut(self) -> &'a mut T;
581
582    /// # Safety
583    /// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
584    /// - 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).
585    unsafe fn deref(self) -> &'a T;
586
587    /// Returns a copy of the contained value.
588    ///
589    /// # Safety
590    /// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
591    /// - 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).
592    unsafe fn read(self) -> T
593    where
594        T: Copy;
595}
596
597impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
598    #[inline]
599    unsafe fn deref_mut(self) -> &'a mut T {
600        // SAFETY: The caller upholds the alias rules.
601        unsafe { &mut *self.get() }
602    }
603    #[inline]
604    unsafe fn deref(self) -> &'a T {
605        // SAFETY: The caller upholds the alias rules.
606        unsafe { &*self.get() }
607    }
608
609    #[inline]
610    unsafe fn read(self) -> T
611    where
612        T: Copy,
613    {
614        // SAFETY: The caller upholds the alias rules.
615        unsafe { self.get().read() }
616    }
617}
618
619trait DebugEnsureAligned {
620    fn debug_ensure_aligned(self) -> Self;
621}
622
623// Disable this for miri runs as it already checks if pointer to reference
624// casts are properly aligned.
625#[cfg(all(debug_assertions, not(miri)))]
626impl<T: Sized> DebugEnsureAligned for *mut T {
627    #[track_caller]
628    fn debug_ensure_aligned(self) -> Self {
629        let align = align_of::<T>();
630        // Implementation shamelessly borrowed from the currently unstable
631        // ptr.is_aligned_to.
632        //
633        // Replace once https://github.com/rust-lang/rust/issues/96284 is stable.
634        assert_eq!(
635            self as usize & (align - 1),
636            0,
637            "pointer is not aligned. Address {:p} does not have alignment {} for type {}",
638            self,
639            align,
640            core::any::type_name::<T>()
641        );
642        self
643    }
644}
645
646#[cfg(any(not(debug_assertions), miri))]
647impl<T: Sized> DebugEnsureAligned for *mut T {
648    #[inline(always)]
649    fn debug_ensure_aligned(self) -> Self {
650        self
651    }
652}