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