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}