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}