Skip to main content

bevy_ptr/
lib.rs

1#![doc = "# Bevy Pointer\n\n[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/bevyengine/bevy#license)\n[![Crates.io](https://img.shields.io/crates/v/bevy_ptr.svg)](https://crates.io/crates/bevy_ptr)\n[![Downloads](https://img.shields.io/crates/d/bevy_ptr.svg)](https://crates.io/crates/bevy_ptr)\n[![Docs](https://docs.rs/bevy_ptr/badge.svg)](https://docs.rs/bevy_ptr/latest/bevy_ptr/)\n[![Discord](https://img.shields.io/discord/691052431525675048.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bevy)\n\nPointers in computer programming are objects that store a memory address. They\'re a fundamental building block for constructing more\ncomplex data structures.\n\nThey\'re also *the* definitive source of memory safety bugs: you can dereference a invalid (null) pointer, access a pointer after the underlying\nmemory has been freed, and even ignore type safety and misread or mutate the underlying memory improperly.\n\nRust is a programming language that heavily relies on its types to enforce correctness, and by proxy, memory safety. As a result,\nRust has an entire zoo of types for working with pointers, and a graph of safe and unsafe conversions that make working with them safer.\n\n`bevy_ptr` is a crate that attempts to bridge the gap between the full blown unsafety of `*mut ()` and the safe `&\'a T`, allowing users\nto choose what invariants to uphold for their pointer, with the intent to enable building progressively safer abstractions.\n\n## How to Build a Borrow (From Scratch)\n\nCorrectly and safety converting a pointer into a valid borrow is at the core of all `unsafe` code in Rust. Looking at the documentation for\n[`(*const T)::as_ref`], a pointer must satisfy *all* of the following conditions:\n\n* The pointer must be properly aligned.\n* The pointer cannot be null, even for zero sized types.\n* The pointer must be within bounds of a valid allocated object (on the stack or the heap).\n* The pointer must point to an initialized instance of `T`.\n* The newly assigned lifetime should be valid for the value that the pointer is targeting.\n* The code must enforce Rust\'s aliasing rules. Only one mutable borrow or arbitrarily many read-only borrows may exist to a value at any given moment\n  in time, and converting from `&T` to `&mut T` is never allowed.\n\nNote these rules aren\'t final and are still in flux as the Rust Project hashes out what exactly are the pointer aliasing rules, but the expectation is that the\nfinal set of constraints are going to be a superset of this list, not a subset.\n\nThis list already is non-trivial to satisfy in isolation. Thankfully, the Rust core/standard library provides a progressive list of pointer types that help\nbuild these safety guarantees...\n\n## Standard Pointers\n\n|Pointer Type       |Lifetime\'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|\n|-------------------|-----------|-------|--------------|-------|--------|----------------|------------------|\n|`Box<T>`           |Owned      |Yes    |Yes           |Yes    |Yes     |Yes             |Yes               |\n|`&\'a mut T`        |Yes        |Yes    |Yes           |Yes    |Yes     |Yes             |Yes               |\n|`&\'a T`            |Yes        |No     |Yes           |Yes    |Yes     |No              |Yes               |\n|`&\'a UnsafeCell<T>`|Yes        |Maybe  |Yes           |Yes    |Yes     |Yes             |Yes               |\n|`NonNull<T>`       |No         |Yes    |Yes           |No     |Yes     |No              |No                |\n|`*const T`         |No         |No     |Yes           |No     |No      |No              |No                |\n|`*mut T`           |No         |Yes    |Yes           |No     |No      |No              |No                |\n|`*const ()`        |No         |No     |No            |No     |No      |No              |No                |\n|`*mut ()`          |No         |Yes    |No            |No     |No      |No              |No                |\n\n`&T`, `&mut T`, and `Box<T>` are by far the most common pointer types that Rust developers will see. They\'re the only ones in this list that are entirely usable\nwithout the use of `unsafe`.\n\n`&UnsafeCell<T>` is the first step away from safety. `UnsafeCell` is the *only* way to get a mutable borrow from an immutable one in the language, so it\'s the\nbase primitive for all interior mutability in the language: `Cell<T>`, `RefCell<T>`, `Mutex<T>`, `RwLock<T>`, etc. are all built on top of\n`UnsafeCell<T>`. To safety convert `&UnsafeCell<T>` into a `&T` or `&mut T`, the caller must guarantee that all simultaneous access follow Rust\'s aliasing rules.\n\n`NonNull<T>` takes quite a step down from the aforementioned types. In addition to allowing aliasing, it\'s the first pointer type on this list to drop both\nlifetimes and the alignment guarantees of borrows. Its only guarantees are that the pointer is not null and that it points to a valid instance\nof type `T`. If you\'ve ever worked with C++, `NonNull<T>` is very close to a C++ reference (`T&`).\n\n`*const T` and `*mut T` are what most developers with a background in C or C++ would consider pointers.\n\n`*const ()` is the bottom of this list. They\'re the Rust equivalent to C\'s `void*`.  Note that Rust doesn\'t formally have a concept of type that holds an arbitrary\nuntyped memory address. Pointing at the unit type (or some other zero-sized type) just happens to be the convention. The only way to reasonably use them is to\ncast back to a typed pointer. They show up occasionally when dealing with FFI and the rare occasion where dynamic dispatch is required, but a trait is too\nconstraining of an interface to work with. A great example of this are the [RawWaker] APIs, where a singular trait (or set of traits) may be insufficient to capture\nall usage patterns. `*mut ()` should only be used to carry the mutability of the target, and as there is no way to mutate an unknown type.\n\n[RawWaker]: https://doc.rust-lang.org/std/task/struct.RawWaker.html\n\n## Available in Nightly\n\n|Pointer Type       |Lifetime\'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|\n|-------------------|-----------|-------|--------------|-------|--------|----------------|------------------|\n|`Unique<T>`        |Owned      |Yes    |Yes           |Yes    |Yes     |Yes             |Yes               |\n|`Shared<T>`        |Owned*     |Yes    |Yes           |Yes    |Yes     |No              |Yes               |\n\n`Unique<T>` is currently available in `core::ptr` on nightly Rust builds. It\'s a pointer type that acts like it owns the value it points to. It can be thought of\nas a `Box<T>` that does not allocate on initialization or deallocated when it\'s dropped, and is in fact used to implement common types like `Box<T>`, `Vec<T>`,\netc.\n\n`Shared<T>` is currently available in `core::ptr` on nightly Rust builds. It\'s the pointer that backs both `Rc<T>` and `Arc<T>`. Its semantics allow for\nmultiple instances to collectively own the data it points to, and as a result, forbids getting a mutable borrow.\n\n`bevy_ptr` does not support these types right now, but may support [polyfills] for these pointer types if the need arises.\n\n[polyfills]: https://en.wikipedia.org/wiki/Polyfill_(programming)\n\n## Available in `bevy_ptr`\n\n|Pointer Type         |Lifetime\'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|\n|---------------------|-----------|-------|--------------|-------|--------|----------------|------------------|\n|`ConstNonNull<T>`    |No         |No     |Yes           |No     |Yes     |No              |Yes               |\n|`ThinSlicePtr<\'a, T>`|Yes        |No     |Yes           |Yes    |Yes     |Yes             |Yes               |\n|`MovingPtr<\'a, T>`   |Yes        |Yes    |Yes           |Maybe  |Yes     |Yes             |Yes               |\n|`OwningPtr<\'a>`      |Yes        |Yes    |No            |Maybe  |Yes     |Yes             |No                |\n|`Ptr<\'a>`            |Yes        |No     |No            |Maybe  |Yes     |No              |No                |\n|`PtrMut<\'a>`         |Yes        |Yes    |No            |Maybe  |Yes     |Yes             |No                |\n\n`ConstNonNull<T>` is like `NonNull<T>` but disallows safe conversions into types that allow mutable access to the value it points to. It\'s the `*const T` to\n`NonNull<T>`\'s `*mut T`.\n\n`ThinSlicePtr<\'a, T>` is a `&\'a [T]` without the slice length. This means it\'s smaller on the stack, but it means bounds checking is impossible locally, so\naccessing elements in the slice is `unsafe`. In debug builds, the length is included and will be checked.\n\n`OwningPtr<\'a>`, `Ptr<\'a>`, and `PtrMut<\'a>` act like `NonNull<()>`, but attempts to restore much of the safety guarantees of `Unique<T>`, `&T`, and `&mut T`.\nThey allow working with heterogenous type erased storage (i.e. ECS tables, typemaps) without the overhead of dynamic dispatch in a manner that progressively\ntranslates back to safe borrows. These types also support optional alignment requirements at a type level, and will verify it on dereference in debug builds.\n\n`MovingPtr<\'a, T>` is like a lifetimed-`Box<T>` or a typed `OwningPtr<\'a>` made for cheaply moving potentially large values around in memory.\nIt\'s a pointer that owns the value it points to but does not own the allocation. If dropped, it will drop the value it points to, just as\nif you dropped a value of the inner type but won\'t deallocate the allocation where the value lived in. It provides a number of methods for moving the value\ninto another location in memory, including options for partial or deconstructive moves.\n"include_str!("../README.md")]
2#![no_std]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![expect(unsafe_code, reason = "Raw pointers are inherently unsafe.")]
5#![doc(
6    html_logo_url = "https://bevy.org/assets/icon.png",
7    html_favicon_url = "https://bevy.org/assets/icon.png"
8)]
9
10use core::{
11    cell::UnsafeCell,
12    fmt::{self, Debug, Formatter, Pointer},
13    marker::PhantomData,
14    mem::{self, ManuallyDrop, MaybeUninit},
15    ops::{Deref, DerefMut},
16    ptr::{self, NonNull},
17};
18
19/// Used as a type argument to [`Ptr`], [`PtrMut`], [`OwningPtr`], and [`MovingPtr`] to specify that the pointer is guaranteed
20/// to be [aligned].
21///
22/// [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
23#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Aligned {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Aligned")
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Aligned { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Aligned {
    #[inline]
    fn clone(&self) -> Aligned { *self }
}Clone)]
24pub struct Aligned;
25
26/// Used as a type argument to [`Ptr`], [`PtrMut`], [`OwningPtr`], and [`MovingPtr`] to specify that the pointer may not [aligned].
27///
28/// [aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
29#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Unaligned {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Unaligned")
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Unaligned { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Unaligned {
    #[inline]
    fn clone(&self) -> Unaligned { *self }
}Clone)]
30pub struct Unaligned;
31
32/// Trait that is only implemented for [`Aligned`] and [`Unaligned`] to work around the lack of ability
33/// to have const generics of an enum.
34pub trait IsAligned: sealed::Sealed {
35    /// Reads the value pointed to by `ptr`.
36    ///
37    /// # Safety
38    ///  - `ptr` must be valid for reads.
39    ///  - `ptr` must point to a valid instance of type `T`
40    ///  - If this type is [`Aligned`], then `ptr` must be [properly aligned] for type `T`.
41    ///
42    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
43    #[doc(hidden)]
44    unsafe fn read_ptr<T>(ptr: *const T) -> T;
45
46    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
47    /// and destination must *not* overlap.
48    ///
49    /// # Safety
50    ///  - `src` must be valid for reads of `count * size_of::<T>()` bytes.
51    ///  - `dst` must be valid for writes of `count * size_of::<T>()` bytes.
52    ///  - The region of memory beginning at `src` with a size of `count *
53    ///    size_of::<T>()` bytes must *not* overlap with the region of memory
54    ///    beginning at `dst` with the same size.
55    ///  - If this type is [`Aligned`], then both `src` and `dst` must properly
56    ///    be aligned for values of type `T`.
57    #[doc(hidden)]
58    unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
59
60    /// Reads the value pointed to by `ptr`.
61    ///
62    /// # Safety
63    ///  - `ptr` must be valid for reads and writes.
64    ///  - `ptr` must point to a valid instance of type `T`
65    ///  - If this type is [`Aligned`], then `ptr` must be [properly aligned] for type `T`.
66    ///  - The value pointed to by `ptr` must be valid for dropping.
67    ///  - While `drop_in_place` is executing, the only way to access parts of `ptr` is through
68    ///    the `&mut Self` supplied to it's `Drop::drop` impl.
69    ///
70    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
71    #[doc(hidden)]
72    unsafe fn drop_in_place<T>(ptr: *mut T);
73}
74
75impl IsAligned for Aligned {
76    #[inline]
77    unsafe fn read_ptr<T>(ptr: *const T) -> T {
78        // SAFETY:
79        //  - The caller is required to ensure that `src` must be valid for reads.
80        //  - The caller is required to ensure that `src` points to a valid instance of type `T`.
81        //  - This type is `Aligned` so the caller must ensure that `src` is properly aligned for type `T`.
82        unsafe { ptr.read() }
83    }
84
85    #[inline]
86    unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
87        // SAFETY:
88        //  - The caller is required to ensure that `src` must be valid for reads.
89        //  - The caller is required to ensure that `dst` must be valid for writes.
90        //  - The caller is required to ensure that `src` and `dst` are aligned.
91        //  - The caller is required to ensure that the memory region covered by `src`
92        //    and `dst`, fitting up to `count` elements do not overlap.
93        unsafe {
94            ptr::copy_nonoverlapping(src, dst, count);
95        }
96    }
97
98    #[inline]
99    unsafe fn drop_in_place<T>(ptr: *mut T) {
100        // SAFETY:
101        //  - The caller is required to ensure that `ptr` must be valid for reads and writes.
102        //  - The caller is required to ensure that `ptr` points to a valid instance of type `T`.
103        //  - This type is `Aligned` so the caller must ensure that `ptr` is properly aligned for type `T`.
104        //  - The caller is required to ensure that `ptr` points must be valid for dropping.
105        //  - The caller is required to ensure that the value `ptr` points must not be used after this function
106        //    call.
107        unsafe {
108            ptr::drop_in_place(ptr);
109        }
110    }
111}
112
113impl IsAligned for Unaligned {
114    #[inline]
115    unsafe fn read_ptr<T>(ptr: *const T) -> T {
116        // SAFETY:
117        //  - The caller is required to ensure that `src` must be valid for reads.
118        //  - The caller is required to ensure that `src` points to a valid instance of type `T`.
119        unsafe { ptr.read_unaligned() }
120    }
121
122    #[inline]
123    unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
124        // SAFETY:
125        //  - The caller is required to ensure that `src` must be valid for reads.
126        //  - The caller is required to ensure that `dst` must be valid for writes.
127        //  - This is doing a byte-wise copy. `src` and `dst` are always guaranteed to be
128        //    aligned.
129        //  - The caller is required to ensure that the memory region covered by `src`
130        //    and `dst`, fitting up to `count` elements do not overlap.
131        unsafe {
132            ptr::copy_nonoverlapping::<u8>(
133                src.cast::<u8>(),
134                dst.cast::<u8>(),
135                count * size_of::<T>(),
136            );
137        }
138    }
139
140    #[inline]
141    unsafe fn drop_in_place<T>(ptr: *mut T) {
142        // SAFETY:
143        //  - The caller is required to ensure that `ptr` must be valid for reads and writes.
144        //  - The caller is required to ensure that `ptr` points to a valid instance of type `T`.
145        //  - This type is not `Aligned` so the caller does not need to ensure that `ptr` is properly aligned for type `T`.
146        //  - The caller is required to ensure that `ptr` points must be valid for dropping.
147        //  - The caller is required to ensure that the value `ptr` points must not be used after this function
148        //    call.
149        unsafe {
150            drop(ptr.read_unaligned());
151        }
152    }
153}
154
155mod sealed {
156    pub trait Sealed {}
157    impl Sealed for super::Aligned {}
158    impl Sealed for super::Unaligned {}
159}
160
161/// A newtype around [`NonNull`] that only allows conversion to read-only borrows or pointers.
162///
163/// This type can be thought of as the `*const T` to [`NonNull<T>`]'s `*mut T`.
164#[derive(#[automatically_derived]
impl<T: ::core::clone::Clone + ?Sized> ::core::clone::Clone for
    ConstNonNull<T> {
    #[inline]
    fn clone(&self) -> ConstNonNull<T> {
        ConstNonNull(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy + ?Sized> ::core::marker::Copy for
    ConstNonNull<T> {
}Copy)]
165#[repr(transparent)]
166pub struct ConstNonNull<T: ?Sized>(NonNull<T>);
167
168impl<T: ?Sized> ConstNonNull<T> {
169    /// Creates a new `ConstNonNull` if `ptr` is non-null.
170    ///
171    /// # Examples
172    ///
173    /// ```
174    /// use bevy_ptr::ConstNonNull;
175    ///
176    /// let x = 0u32;
177    /// let ptr = ConstNonNull::<u32>::new(&x as *const _).expect("ptr is null!");
178    ///
179    /// if let Some(ptr) = ConstNonNull::<u32>::new(core::ptr::null()) {
180    ///     unreachable!();
181    /// }
182    /// ```
183    pub fn new(ptr: *const T) -> Option<Self> {
184        NonNull::new(ptr.cast_mut()).map(Self)
185    }
186
187    /// Creates a new `ConstNonNull`.
188    ///
189    /// # Safety
190    ///
191    /// `ptr` must be non-null.
192    ///
193    /// # Examples
194    ///
195    /// ```
196    /// use bevy_ptr::ConstNonNull;
197    ///
198    /// let x = 0u32;
199    /// let ptr = unsafe { ConstNonNull::new_unchecked(&x as *const _) };
200    /// ```
201    ///
202    /// *Incorrect* usage of this function:
203    ///
204    /// ```rust,no_run
205    /// use bevy_ptr::ConstNonNull;
206    ///
207    /// // NEVER DO THAT!!! This is undefined behavior. ⚠️
208    /// let ptr = unsafe { ConstNonNull::<u32>::new_unchecked(core::ptr::null()) };
209    /// ```
210    pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
211        // SAFETY: This function's safety invariants are identical to `NonNull::new_unchecked`
212        // The caller must satisfy all of them.
213        unsafe { Self(NonNull::new_unchecked(ptr.cast_mut())) }
214    }
215
216    /// Returns a shared reference to the value.
217    ///
218    /// # Safety
219    ///
220    /// When calling this method, you have to ensure that all of the following is true:
221    ///
222    /// * The pointer must be [properly aligned].
223    ///
224    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
225    ///
226    /// * The pointer must point to an initialized instance of `T`.
227    ///
228    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
229    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
230    ///   In particular, while this reference exists, the memory the pointer points to must
231    ///   not get mutated (except inside `UnsafeCell`).
232    ///
233    /// This applies even if the result of this method is unused!
234    /// (The part about being initialized is not yet fully decided, but until
235    /// it is, the only safe approach is to ensure that they are indeed initialized.)
236    ///
237    /// # Examples
238    ///
239    /// ```
240    /// use bevy_ptr::ConstNonNull;
241    ///
242    /// let mut x = 0u32;
243    /// let ptr = ConstNonNull::new(&mut x as *mut _).expect("ptr is null!");
244    ///
245    /// let ref_x = unsafe { ptr.as_ref() };
246    /// println!("{ref_x}");
247    /// ```
248    ///
249    /// [the module documentation]: core::ptr#safety
250    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
251    #[inline]
252    pub unsafe fn as_ref<'a>(&self) -> &'a T {
253        // SAFETY: This function's safety invariants are identical to `NonNull::as_ref`
254        // The caller must satisfy all of them.
255        unsafe { self.0.as_ref() }
256    }
257}
258
259impl<T: ?Sized> From<NonNull<T>> for ConstNonNull<T> {
260    fn from(value: NonNull<T>) -> ConstNonNull<T> {
261        ConstNonNull(value)
262    }
263}
264
265impl<'a, T: ?Sized> From<&'a T> for ConstNonNull<T> {
266    fn from(value: &'a T) -> ConstNonNull<T> {
267        ConstNonNull(NonNull::from(value))
268    }
269}
270
271impl<'a, T: ?Sized> From<&'a mut T> for ConstNonNull<T> {
272    fn from(value: &'a mut T) -> ConstNonNull<T> {
273        ConstNonNull(NonNull::from(value))
274    }
275}
276
277/// Type-erased borrow of some unknown type chosen when constructing this type.
278///
279/// This type tries to act "borrow-like" which means that:
280/// - It should be considered immutable: its target must not be changed while this pointer is alive.
281/// - It must always point to a valid value of whatever the pointee type is.
282/// - The lifetime `'a` accurately represents how long the pointer is valid for.
283/// - If `A` is [`Aligned`], the pointer must always be [properly aligned] for the unknown pointee type.
284///
285/// It may be helpful to think of this type as similar to `&'a dyn Any` but without
286/// the metadata and able to point to data that does not correspond to a Rust type.
287///
288/// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
289#[derive(#[automatically_derived]
impl<'a, A: ::core::marker::Copy + IsAligned> ::core::marker::Copy for
    Ptr<'a, A> {
}Copy, #[automatically_derived]
impl<'a, A: ::core::clone::Clone + IsAligned> ::core::clone::Clone for
    Ptr<'a, A> {
    #[inline]
    fn clone(&self) -> Ptr<'a, A> {
        Ptr(::core::clone::Clone::clone(&self.0),
            ::core::clone::Clone::clone(&self.1))
    }
}Clone)]
290#[repr(transparent)]
291pub struct Ptr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a u8, A)>);
292
293/// Type-erased mutable borrow of some unknown type chosen when constructing this type.
294///
295/// This type tries to act "borrow-like" which means that:
296/// - Pointer is considered exclusive and mutable. It cannot be cloned as this would lead to
297///   aliased mutability.
298/// - It must always point to a valid value of whatever the pointee type is.
299/// - The lifetime `'a` accurately represents how long the pointer is valid for.
300/// - If `A` is [`Aligned`], the pointer must always be [properly aligned] for the unknown pointee type.
301///
302/// It may be helpful to think of this type as similar to `&'a mut dyn Any` but without
303/// the metadata and able to point to data that does not correspond to a Rust type.
304///
305/// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
306#[repr(transparent)]
307pub struct PtrMut<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
308
309/// Type-erased [`Box`]-like pointer to some unknown type chosen when constructing this type.
310///
311/// Conceptually represents ownership of whatever data is being pointed to and so is
312/// responsible for calling its `Drop` impl. This pointer is _not_ responsible for freeing
313/// the memory pointed to by this pointer as it may be pointing to an element in a `Vec` or
314/// to a local in a function etc.
315///
316/// This type tries to act "borrow-like" which means that:
317/// - Pointer should be considered exclusive and mutable. It cannot be cloned as this would lead
318///   to aliased mutability and potentially use after free bugs.
319/// - It must always point to a valid value of whatever the pointee type is.
320/// - The lifetime `'a` accurately represents how long the pointer is valid for.
321/// - If `A` is [`Aligned`], the pointer must always be [properly aligned] for the unknown pointee type.
322///
323/// It may be helpful to think of this type as similar to `&'a mut ManuallyDrop<dyn Any>` but
324/// without the metadata and able to point to data that does not correspond to a Rust type.
325///
326/// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
327/// [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html
328#[repr(transparent)]
329pub struct OwningPtr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
330
331/// A [`Box`]-like pointer for moving a value to a new memory location without needing to pass by
332/// value.
333///
334/// Conceptually represents ownership of whatever data is being pointed to and will call its
335/// [`Drop`] impl upon being dropped. This pointer is _not_ responsible for freeing
336/// the memory pointed to by this pointer as it may be pointing to an element in a `Vec` or
337/// to a local in a function etc.
338///
339/// This type tries to act "borrow-like" which means that:
340/// - Pointer should be considered exclusive and mutable. It cannot be cloned as this would lead
341///   to aliased mutability and potentially use after free bugs.
342/// - It must always point to a valid value of whatever the pointee type is.
343/// - The lifetime `'a` accurately represents how long the pointer is valid for.
344/// - It does not support pointer arithmetic in any way.
345/// - If `A` is [`Aligned`], the pointer must always be [properly aligned] for the type `T`.
346///
347/// A value can be deconstructed into its fields via [`deconstruct_moving_ptr`], see it's documentation
348/// for an example on how to use it.
349///
350/// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
351/// [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html
352#[repr(transparent)]
353pub struct MovingPtr<'a, T, A: IsAligned = Aligned>(NonNull<T>, PhantomData<(&'a mut T, A)>);
354
355macro_rules! impl_ptr {
356    ($ptr:ident) => {
357        impl<'a> $ptr<'a, Aligned> {
358            /// Removes the alignment requirement of this pointer
359            pub fn to_unaligned(self) -> $ptr<'a, Unaligned> {
360                $ptr(self.0, PhantomData)
361            }
362        }
363
364        impl<'a, A: IsAligned> From<$ptr<'a, A>> for NonNull<u8> {
365            fn from(ptr: $ptr<'a, A>) -> Self {
366                ptr.0
367            }
368        }
369
370        impl<A: IsAligned> $ptr<'_, A> {
371            /// Calculates the offset from a pointer.
372            /// As the pointer is type-erased, there is no size information available. The provided
373            /// `count` parameter is in raw bytes.
374            ///
375            /// *See also: [`ptr::offset`][ptr_offset]*
376            ///
377            /// # Safety
378            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
379            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
380            ///   be unaligned for the pointee type.
381            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
382            ///
383            /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
384            #[inline]
385            pub unsafe fn byte_offset(self, count: isize) -> Self {
386                Self(
387                    // SAFETY: The caller upholds safety for `offset` and ensures the result is not null.
388                    unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
389                    PhantomData,
390                )
391            }
392
393            /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
394            /// As the pointer is type-erased, there is no size information available. The provided
395            /// `count` parameter is in raw bytes.
396            ///
397            /// *See also: [`ptr::add`][ptr_add]*
398            ///
399            /// # Safety
400            /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
401            /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
402            ///   be unaligned for the pointee type.
403            /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
404            ///
405            /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
406            #[inline]
407            pub unsafe fn byte_add(self, count: usize) -> Self {
408                Self(
409                    // SAFETY: The caller upholds safety for `add` and ensures the result is not null.
410                    unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
411                    PhantomData,
412                )
413            }
414        }
415
416        impl<A: IsAligned> Pointer for $ptr<'_, A> {
417            #[inline]
418            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
419                Pointer::fmt(&self.0, f)
420            }
421        }
422
423        impl Debug for $ptr<'_, Aligned> {
424            #[inline]
425            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
426                write!(f, "{}<Aligned>({:?})", stringify!($ptr), self.0)
427            }
428        }
429
430        impl Debug for $ptr<'_, Unaligned> {
431            #[inline]
432            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
433                write!(f, "{}<Unaligned>({:?})", stringify!($ptr), self.0)
434            }
435        }
436    };
437}
438
439impl<'a> Ptr<'a, Aligned> {
    /// Removes the alignment requirement of this pointer
    pub fn to_unaligned(self) -> Ptr<'a, Unaligned> {
        Ptr(self.0, PhantomData)
    }
}
impl<'a, A: IsAligned> From<Ptr<'a, A>> for NonNull<u8> {
    fn from(ptr: Ptr<'a, A>) -> Self { ptr.0 }
}
impl<A: IsAligned> Ptr<'_, A> {
    /// Calculates the offset from a pointer.
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::offset`][ptr_offset]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
    #[inline]
    pub unsafe fn byte_offset(self, count: isize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
            PhantomData)
    }
    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::add`][ptr_add]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
    #[inline]
    pub unsafe fn byte_add(self, count: usize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
            PhantomData)
    }
}
impl<A: IsAligned> Pointer for Ptr<'_, A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        Pointer::fmt(&self.0, f)
    }
}
impl Debug for Ptr<'_, Aligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Aligned>({1:?})", "Ptr", self.0))
    }
}
impl Debug for Ptr<'_, Unaligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Unaligned>({1:?})", "Ptr", self.0))
    }
}impl_ptr!(Ptr);
440impl<'a> PtrMut<'a, Aligned> {
    /// Removes the alignment requirement of this pointer
    pub fn to_unaligned(self) -> PtrMut<'a, Unaligned> {
        PtrMut(self.0, PhantomData)
    }
}
impl<'a, A: IsAligned> From<PtrMut<'a, A>> for NonNull<u8> {
    fn from(ptr: PtrMut<'a, A>) -> Self { ptr.0 }
}
impl<A: IsAligned> PtrMut<'_, A> {
    /// Calculates the offset from a pointer.
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::offset`][ptr_offset]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
    #[inline]
    pub unsafe fn byte_offset(self, count: isize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
            PhantomData)
    }
    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::add`][ptr_add]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
    #[inline]
    pub unsafe fn byte_add(self, count: usize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
            PhantomData)
    }
}
impl<A: IsAligned> Pointer for PtrMut<'_, A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        Pointer::fmt(&self.0, f)
    }
}
impl Debug for PtrMut<'_, Aligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Aligned>({1:?})", "PtrMut", self.0))
    }
}
impl Debug for PtrMut<'_, Unaligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Unaligned>({1:?})", "PtrMut", self.0))
    }
}impl_ptr!(PtrMut);
441impl<'a> OwningPtr<'a, Aligned> {
    /// Removes the alignment requirement of this pointer
    pub fn to_unaligned(self) -> OwningPtr<'a, Unaligned> {
        OwningPtr(self.0, PhantomData)
    }
}
impl<'a, A: IsAligned> From<OwningPtr<'a, A>> for NonNull<u8> {
    fn from(ptr: OwningPtr<'a, A>) -> Self { ptr.0 }
}
impl<A: IsAligned> OwningPtr<'_, A> {
    /// Calculates the offset from a pointer.
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::offset`][ptr_offset]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_offset]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
    #[inline]
    pub unsafe fn byte_offset(self, count: isize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().offset(count)) },
            PhantomData)
    }
    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
    /// As the pointer is type-erased, there is no size information available. The provided
    /// `count` parameter is in raw bytes.
    ///
    /// *See also: [`ptr::add`][ptr_add]*
    ///
    /// # Safety
    /// - The offset cannot make the existing ptr null, or take it out of bounds for its allocation.
    /// - If the `A` type parameter is [`Aligned`] then the offset must not make the resulting pointer
    ///   be unaligned for the pointee type.
    /// - The value pointed by the resulting pointer must outlive the lifetime of this pointer.
    ///
    /// [ptr_add]: https://doc.rust-lang.org/std/primitive.pointer.html#method.add
    #[inline]
    pub unsafe fn byte_add(self, count: usize) -> Self {
        Self(unsafe { NonNull::new_unchecked(self.as_ptr().add(count)) },
            PhantomData)
    }
}
impl<A: IsAligned> Pointer for OwningPtr<'_, A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        Pointer::fmt(&self.0, f)
    }
}
impl Debug for OwningPtr<'_, Aligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Aligned>({1:?})", "OwningPtr", self.0))
    }
}
impl Debug for OwningPtr<'_, Unaligned> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{0}<Unaligned>({1:?})", "OwningPtr",
                self.0))
    }
}impl_ptr!(OwningPtr);
442
443impl<'a, T> MovingPtr<'a, T, Aligned> {
444    /// Removes the alignment requirement of this pointer
445    #[inline]
446    pub fn to_unaligned(self) -> MovingPtr<'a, T, Unaligned> {
447        let value = MovingPtr(self.0, PhantomData);
448        mem::forget(self);
449        value
450    }
451
452    /// Creates a [`MovingPtr`] from a provided value of type `T`.
453    ///
454    /// For a safer alternative, it is strongly advised to use [`move_as_ptr`] where possible.
455    ///
456    /// # Safety
457    /// - `value` must store a properly initialized value of type `T`.
458    /// - Once the returned [`MovingPtr`] has been used, `value` must be treated as
459    ///   it were uninitialized unless it was explicitly leaked via [`core::mem::forget`].
460    #[inline]
461    pub unsafe fn from_value(value: &'a mut MaybeUninit<T>) -> Self {
462        // SAFETY:
463        // - MaybeUninit<T> has the same memory layout as T
464        // - The caller guarantees that `value` must point to a valid instance of type `T`.
465        MovingPtr(NonNull::from(value).cast::<T>(), PhantomData)
466    }
467}
468
469impl<'a, T, A: IsAligned> MovingPtr<'a, T, A> {
470    /// Creates a new instance from a raw pointer.
471    ///
472    /// For a safer alternative, it is strongly advised to use [`move_as_ptr`] where possible.
473    ///
474    /// # Safety
475    /// - `inner` must point to valid value of `T`.
476    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for `T`.
477    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
478    /// - The lifetime `'a` must be constrained such that this [`MovingPtr`] will stay valid and nothing
479    ///   else can read or mutate the pointee while this [`MovingPtr`] is live.
480    ///
481    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
482    #[inline]
483    pub unsafe fn new(inner: NonNull<T>) -> Self {
484        Self(inner, PhantomData)
485    }
486
487    /// Partially moves out some fields inside of `self`.
488    ///
489    /// The partially returned value is returned back pointing to [`MaybeUninit<T>`].
490    ///
491    /// While calling this function is safe, care must be taken with the returned `MovingPtr` as it
492    /// points to a value that may no longer be completely valid.
493    ///
494    /// # Example
495    ///
496    /// ```
497    /// use core::mem::{offset_of, MaybeUninit, forget};
498    /// use bevy_ptr::{MovingPtr, move_as_ptr};
499    /// # struct FieldAType(usize);
500    /// # struct FieldBType(usize);
501    /// # struct FieldCType(usize);
502    /// # fn insert<T>(_ptr: MovingPtr<'_, T>) {}
503    ///
504    /// struct Parent {
505    ///   field_a: FieldAType,
506    ///   field_b: FieldBType,
507    ///   field_c: FieldCType,
508    /// }
509    ///
510    /// # let parent = Parent {
511    /// #   field_a: FieldAType(0),
512    /// #   field_b: FieldBType(0),
513    /// #   field_c: FieldCType(0),
514    /// # };
515    ///
516    /// // Converts `parent` into a `MovingPtr`
517    /// move_as_ptr!(parent);
518    ///
519    /// // SAFETY:
520    /// // - `field_a` and `field_b` are both unique.
521    /// let (partial_parent, ()) = MovingPtr::partial_move(parent, |parent_ptr| unsafe {
522    ///   bevy_ptr::deconstruct_moving_ptr!({
523    ///     let Parent { field_a, field_b, field_c } = parent_ptr;
524    ///   });
525    ///   
526    ///   insert(field_a);
527    ///   insert(field_b);
528    ///   forget(field_c);
529    /// });
530    ///
531    /// // Move the rest of fields out of the parent.
532    /// // SAFETY:
533    /// // - `field_c` is by itself unique and does not conflict with the previous accesses
534    /// //   inside `partial_move`.
535    /// unsafe {
536    ///   bevy_ptr::deconstruct_moving_ptr!({
537    ///     let MaybeUninit::<Parent> { field_a: _, field_b: _, field_c } = partial_parent;
538    ///   });
539    ///
540    ///   insert(field_c);
541    /// }
542    /// ```
543    ///
544    /// [`forget`]: core::mem::forget
545    #[inline]
546    pub fn partial_move<R>(
547        self,
548        f: impl FnOnce(MovingPtr<'_, T, A>) -> R,
549    ) -> (MovingPtr<'a, MaybeUninit<T>, A>, R) {
550        let partial_ptr = self.0;
551        let ret = f(self);
552        (
553            MovingPtr(partial_ptr.cast::<MaybeUninit<T>>(), PhantomData),
554            ret,
555        )
556    }
557
558    /// Reads the value pointed to by this pointer.
559    #[inline]
560    pub fn read(self) -> T {
561        // SAFETY:
562        //  - `self.0` must be valid for reads as this type owns the value it points to.
563        //  - `self.0` must always point to a valid instance of type `T`
564        //  - If `A` is [`Aligned`], then `ptr` must be properly aligned for type `T`.
565        let value = unsafe { A::read_ptr(self.0.as_ptr()) };
566        mem::forget(self);
567        value
568    }
569
570    /// Writes the value pointed to by this pointer to a provided location.
571    ///
572    /// This does *not* drop the value stored at `dst` and it's the caller's responsibility
573    /// to ensure that it's properly dropped.
574    ///
575    /// # Safety
576    ///  - `dst` must be valid for writes.
577    ///  - If the `A` type parameter is [`Aligned`] then `dst` must be [properly aligned] for `T`.
578    ///
579    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
580    #[inline]
581    pub unsafe fn write_to(self, dst: *mut T) {
582        let src = self.0.as_ptr();
583        mem::forget(self);
584        // SAFETY:
585        //  - `src` must be valid for reads as this pointer is considered to own the value it points to.
586        //  - The caller is required to ensure that `dst` must be valid for writes.
587        //  - As `A` is `Aligned`, the caller is required to ensure that `dst` is aligned and `src` must
588        //    be aligned by the type's invariants.
589        unsafe { A::copy_nonoverlapping(src, dst, 1) };
590    }
591
592    /// Writes the value pointed to by this pointer into `dst`.
593    ///
594    /// The value previously stored at `dst` will be dropped.
595    #[inline]
596    pub fn assign_to(self, dst: &mut T) {
597        // SAFETY:
598        // - `dst` is a mutable borrow, it must point to a valid instance of `T`.
599        // - `dst` is a mutable borrow, it must point to value that is valid for dropping.
600        // - `dst` is a mutable borrow, it must not alias any other access.
601        unsafe {
602            ptr::drop_in_place(dst);
603        }
604        // SAFETY:
605        // - `dst` is a mutable borrow, it must be valid for writes.
606        // - `dst` is a mutable borrow, it must always be aligned.
607        unsafe {
608            self.write_to(dst);
609        }
610    }
611
612    /// Creates a [`MovingPtr`] for a specific field within `self`.
613    ///
614    /// This function is explicitly made for deconstructive moves.
615    ///
616    /// The correct `byte_offset` for a field can be obtained via [`core::mem::offset_of`].
617    ///
618    /// # Safety
619    ///  - `f` must return a non-null pointer to a valid field inside `T`
620    ///  - If `A` is [`Aligned`], then `T` must not be `repr(packed)`
621    ///  - `self` should not be accessed or dropped as if it were a complete value after this function returns.
622    ///    Other fields that have not been moved out of may still be accessed or dropped separately.
623    ///  - This function cannot alias the field with any other access, including other calls to [`move_field`]
624    ///    for the same field, without first calling [`forget`] on it first.
625    ///
626    /// A result of the above invariants means that any operation that could cause `self` to be dropped while
627    /// the pointers to the fields are held will result in undefined behavior. This requires extra caution
628    /// around code that may panic. See the example below for an example of how to safely use this function.
629    ///
630    /// # Example
631    ///
632    /// ```
633    /// use core::mem::offset_of;
634    /// use bevy_ptr::{MovingPtr, move_as_ptr};
635    /// # struct FieldAType(usize);
636    /// # struct FieldBType(usize);
637    /// # struct FieldCType(usize);
638    /// # fn insert<T>(_ptr: MovingPtr<'_, T>) {}
639    ///
640    /// struct Parent {
641    ///   field_a: FieldAType,
642    ///   field_b: FieldBType,
643    ///   field_c: FieldCType,
644    /// }
645    ///
646    /// let parent = Parent {
647    ///    field_a: FieldAType(0),
648    ///    field_b: FieldBType(0),
649    ///    field_c: FieldCType(0),
650    /// };
651    ///
652    /// // Converts `parent` into a `MovingPtr`.
653    /// move_as_ptr!(parent);
654    ///
655    /// unsafe {
656    ///    let field_a = parent.move_field(|ptr| &raw mut (*ptr).field_a);
657    ///    let field_b = parent.move_field(|ptr| &raw mut (*ptr).field_b);
658    ///    let field_c = parent.move_field(|ptr| &raw mut (*ptr).field_c);
659    ///    // Each call to insert may panic! Ensure that `parent_ptr` cannot be dropped before
660    ///    // calling them!
661    ///    core::mem::forget(parent);
662    ///    insert(field_a);
663    ///    insert(field_b);
664    ///    insert(field_c);
665    /// }
666    /// ```
667    ///
668    /// [`forget`]: core::mem::forget
669    /// [`move_field`]: Self::move_field
670    #[inline(always)]
671    pub unsafe fn move_field<U>(&self, f: impl Fn(*mut T) -> *mut U) -> MovingPtr<'a, U, A> {
672        MovingPtr(
673            // SAFETY: The caller must ensure that `U` is the correct type for the field at `byte_offset`.
674            unsafe { NonNull::new_unchecked(f(self.0.as_ptr())) },
675            PhantomData,
676        )
677    }
678}
679
680impl<'a, T, A: IsAligned> MovingPtr<'a, MaybeUninit<T>, A> {
681    /// Creates a [`MovingPtr`] for a specific field within `self`.
682    ///
683    /// This function is explicitly made for deconstructive moves.
684    ///
685    /// The correct `byte_offset` for a field can be obtained via [`core::mem::offset_of`].
686    ///
687    /// # Safety
688    ///  - `f` must return a non-null pointer to a valid field inside `T`
689    ///  - If `A` is [`Aligned`], then `T` must not be `repr(packed)`
690    ///  - `self` should not be accessed or dropped as if it were a complete value after this function returns.
691    ///    Other fields that have not been moved out of may still be accessed or dropped separately.
692    ///  - This function cannot alias the field with any other access, including other calls to [`move_field`]
693    ///    for the same field, without first calling [`forget`] on it first.
694    ///
695    /// [`forget`]: core::mem::forget
696    /// [`move_field`]: Self::move_field
697    #[inline(always)]
698    pub unsafe fn move_maybe_uninit_field<U>(
699        &self,
700        f: impl Fn(*mut T) -> *mut U,
701    ) -> MovingPtr<'a, MaybeUninit<U>, A> {
702        let self_ptr = self.0.as_ptr().cast::<T>();
703        // SAFETY:
704        // - The caller must ensure that `U` is the correct type for the field at `byte_offset` and thus
705        //   cannot be null.
706        // - `MaybeUninit<T>` is `repr(transparent)` and thus must have the same memory layout as `T``
707        let field_ptr = unsafe { NonNull::new_unchecked(f(self_ptr)) };
708        MovingPtr(field_ptr.cast::<MaybeUninit<U>>(), PhantomData)
709    }
710}
711
712impl<'a, T, A: IsAligned> MovingPtr<'a, MaybeUninit<T>, A> {
713    /// Creates a [`MovingPtr`] pointing to a valid instance of `T`.
714    ///
715    /// See also: [`MaybeUninit::assume_init`].
716    ///
717    /// # Safety
718    /// It's up to the caller to ensure that the value pointed to by `self`
719    /// is really in an initialized state. Calling this when the content is not yet
720    /// fully initialized causes immediate undefined behavior.
721    #[inline]
722    pub unsafe fn assume_init(self) -> MovingPtr<'a, T, A> {
723        let value = MovingPtr(self.0.cast::<T>(), PhantomData);
724        mem::forget(self);
725        value
726    }
727}
728
729impl<T, A: IsAligned> Pointer for MovingPtr<'_, T, A> {
730    #[inline]
731    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
732        Pointer::fmt(&self.0, f)
733    }
734}
735
736impl<T> Debug for MovingPtr<'_, T, Aligned> {
737    #[inline]
738    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
739        f.write_fmt(format_args!("MovingPtr<Aligned>({0:?})", self.0))write!(f, "MovingPtr<Aligned>({:?})", self.0)
740    }
741}
742
743impl<T> Debug for MovingPtr<'_, T, Unaligned> {
744    #[inline]
745    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
746        f.write_fmt(format_args!("MovingPtr<Unaligned>({0:?})", self.0))write!(f, "MovingPtr<Unaligned>({:?})", self.0)
747    }
748}
749
750impl<'a, T, A: IsAligned> From<MovingPtr<'a, T, A>> for OwningPtr<'a, A> {
751    #[inline]
752    fn from(value: MovingPtr<'a, T, A>) -> Self {
753        // SAFETY:
754        // - `value.0` must always point to valid value of type `T`.
755        // - The type parameter `A` is mirrored from input to output, keeping the same alignment guarantees.
756        // - `value.0` by construction must have correct provenance to allow read and writes of type `T`.
757        // - The lifetime `'a` is mirrored from input to output, keeping the same lifetime guarantees.
758        // - `OwningPtr` maintains the same aliasing invariants as `MovingPtr`.
759        let ptr = unsafe { OwningPtr::new(value.0.cast::<u8>()) };
760        mem::forget(value);
761        ptr
762    }
763}
764
765impl<'a, T> TryFrom<MovingPtr<'a, T, Unaligned>> for MovingPtr<'a, T, Aligned> {
766    type Error = MovingPtr<'a, T, Unaligned>;
767    #[inline]
768    fn try_from(value: MovingPtr<'a, T, Unaligned>) -> Result<Self, Self::Error> {
769        let ptr = value.0;
770        if ptr.as_ptr().is_aligned() {
771            mem::forget(value);
772            Ok(MovingPtr(ptr, PhantomData))
773        } else {
774            Err(value)
775        }
776    }
777}
778
779impl<T> Deref for MovingPtr<'_, T, Aligned> {
780    type Target = T;
781    #[inline]
782    fn deref(&self) -> &Self::Target {
783        let ptr = self.0.as_ptr().debug_ensure_aligned();
784        // SAFETY: This type owns the value it points to and the generic type parameter is `A` so this pointer must be aligned.
785        unsafe { &*ptr }
786    }
787}
788
789impl<T> DerefMut for MovingPtr<'_, T, Aligned> {
790    #[inline]
791    fn deref_mut(&mut self) -> &mut Self::Target {
792        let ptr = self.0.as_ptr().debug_ensure_aligned();
793        // SAFETY: This type owns the value it points to and the generic type parameter is `A` so this pointer must be aligned.
794        unsafe { &mut *ptr }
795    }
796}
797
798impl<T, A: IsAligned> Drop for MovingPtr<'_, T, A> {
799    fn drop(&mut self) {
800        // SAFETY:
801        //  - `self.0` must be valid for reads and writes as this pointer type owns the value it points to.
802        //  - `self.0` must always point to a valid instance of type `T`
803        //  - If `A` is `Aligned`, then `ptr` must be properly aligned for type `T` by construction.
804        //  - `self.0` owns the value it points to so it must always be valid for dropping until this pointer is dropped.
805        //  - This type owns the value it points to, so it's required to not mutably alias value that it points to.
806        unsafe { A::drop_in_place(self.0.as_ptr()) };
807    }
808}
809
810impl<'a, A: IsAligned> Ptr<'a, A> {
811    /// Creates a new instance from a raw pointer.
812    ///
813    /// # Safety
814    /// - `inner` must point to valid value of whatever the pointee type is.
815    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
816    /// - `inner` must have correct provenance to allow reads of the pointee type.
817    /// - The lifetime `'a` must be constrained such that this [`Ptr`] will stay valid and nothing
818    ///   can mutate the pointee while this [`Ptr`] is live except through an [`UnsafeCell`].
819    ///
820    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
821    #[inline]
822    pub unsafe fn new(inner: NonNull<u8>) -> Self {
823        Self(inner, PhantomData)
824    }
825
826    /// Transforms this [`Ptr`] into an [`PtrMut`]
827    ///
828    /// # Safety
829    /// * The data pointed to by this `Ptr` must be valid for writes.
830    /// * There must be no active references (mutable or otherwise) to the data underlying this `Ptr`.
831    /// * Another [`PtrMut`] for the same [`Ptr`] must not be created until the first is dropped.
832    #[inline]
833    pub unsafe fn assert_unique(self) -> PtrMut<'a, A> {
834        PtrMut(self.0, PhantomData)
835    }
836
837    /// Transforms this [`Ptr<T>`] into a `&T` with the same lifetime
838    ///
839    /// # Safety
840    /// - `T` must be the erased pointee type for this [`Ptr`].
841    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
842    ///   for the pointee type `T`.
843    ///
844    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
845    #[inline]
846    pub unsafe fn deref<T>(self) -> &'a T {
847        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
848        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
849        unsafe { &*ptr }
850    }
851
852    /// Gets the underlying pointer, erasing the associated lifetime.
853    ///
854    /// If possible, it is strongly encouraged to use [`deref`](Self::deref) over this function,
855    /// as it retains the lifetime.
856    #[inline]
857    pub fn as_ptr(self) -> *mut u8 {
858        self.0.as_ptr()
859    }
860}
861
862impl<'a, T: ?Sized> From<&'a T> for Ptr<'a> {
863    #[inline]
864    fn from(val: &'a T) -> Self {
865        // SAFETY: The returned pointer has the same lifetime as the passed reference.
866        // Access is immutable.
867        unsafe { Self::new(NonNull::from(val).cast()) }
868    }
869}
870
871impl<'a, A: IsAligned> PtrMut<'a, A> {
872    /// Creates a new instance from a raw pointer.
873    ///
874    /// # Safety
875    /// - `inner` must point to valid value of whatever the pointee type is.
876    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
877    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
878    /// - The lifetime `'a` must be constrained such that this [`PtrMut`] will stay valid and nothing
879    ///   else can read or mutate the pointee while this [`PtrMut`] is live.
880    ///
881    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
882    #[inline]
883    pub unsafe fn new(inner: NonNull<u8>) -> Self {
884        Self(inner, PhantomData)
885    }
886
887    /// Transforms this [`PtrMut`] into an [`OwningPtr`]
888    ///
889    /// # Safety
890    /// Must have right to drop or move out of [`PtrMut`].
891    #[inline]
892    pub unsafe fn promote(self) -> OwningPtr<'a, A> {
893        OwningPtr(self.0, PhantomData)
894    }
895
896    /// Transforms this [`PtrMut<T>`] into a `&mut T` with the same lifetime
897    ///
898    /// # Safety
899    /// - `T` must be the erased pointee type for this [`PtrMut`].
900    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
901    ///   for the pointee type `T`.
902    ///
903    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
904    #[inline]
905    pub unsafe fn deref_mut<T>(self) -> &'a mut T {
906        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
907        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
908        unsafe { &mut *ptr }
909    }
910
911    /// Gets the underlying pointer, erasing the associated lifetime.
912    ///
913    /// If possible, it is strongly encouraged to use [`deref_mut`](Self::deref_mut) over
914    /// this function, as it retains the lifetime.
915    #[inline]
916    pub fn as_ptr(&self) -> *mut u8 {
917        self.0.as_ptr()
918    }
919
920    /// Gets a [`PtrMut`] from this with a smaller lifetime.
921    #[inline]
922    pub fn reborrow(&mut self) -> PtrMut<'_, A> {
923        // SAFETY: the ptrmut we're borrowing from is assumed to be valid
924        unsafe { PtrMut::new(self.0) }
925    }
926
927    /// Gets an immutable reference from this mutable reference
928    #[inline]
929    pub fn as_ref(&self) -> Ptr<'_, A> {
930        // SAFETY: The `PtrMut` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
931        unsafe { Ptr::new(self.0) }
932    }
933}
934
935impl<'a, T: ?Sized> From<&'a mut T> for PtrMut<'a> {
936    #[inline]
937    fn from(val: &'a mut T) -> Self {
938        // SAFETY: The returned pointer has the same lifetime as the passed reference.
939        // The reference is mutable, and thus will not alias.
940        unsafe { Self::new(NonNull::from(val).cast()) }
941    }
942}
943
944impl<'a> OwningPtr<'a> {
945    /// This exists mostly to reduce compile times;
946    /// code is only duplicated per type, rather than per function called.
947    ///
948    /// # Safety
949    ///
950    /// Safety constraints of [`PtrMut::promote`] must be upheld.
951    unsafe fn make_internal<T>(temp: &mut ManuallyDrop<T>) -> OwningPtr<'_> {
952        // SAFETY: The constraints of `promote` are upheld by caller.
953        unsafe { PtrMut::from(&mut *temp).promote() }
954    }
955
956    /// Consumes a value and creates an [`OwningPtr`] to it while ensuring a double drop does not happen.
957    #[inline]
958    pub fn make<T, F: FnOnce(OwningPtr<'_>) -> R, R>(val: T, f: F) -> R {
959        let mut val = ManuallyDrop::new(val);
960        // SAFETY: The value behind the pointer will not get dropped or observed later,
961        // so it's safe to promote it to an owning pointer.
962        f(unsafe { Self::make_internal(&mut val) })
963    }
964}
965
966impl<'a, A: IsAligned> OwningPtr<'a, A> {
967    /// Creates a new instance from a raw pointer.
968    ///
969    /// # Safety
970    /// - `inner` must point to valid value of whatever the pointee type is.
971    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
972    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
973    /// - The lifetime `'a` must be constrained such that this [`OwningPtr`] will stay valid and nothing
974    ///   else can read or mutate the pointee while this [`OwningPtr`] is live.
975    ///
976    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
977    #[inline]
978    pub unsafe fn new(inner: NonNull<u8>) -> Self {
979        Self(inner, PhantomData)
980    }
981
982    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
983    ///
984    /// # Safety
985    /// - `T` must be the erased pointee type for this [`OwningPtr`].
986    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
987    ///   for the pointee type `T`.
988    ///
989    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
990    #[inline]
991    pub unsafe fn read<T>(self) -> T {
992        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
993        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
994        unsafe { ptr.read() }
995    }
996
997    /// Casts to a concrete type as a [`MovingPtr`].
998    ///
999    /// # Safety
1000    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1001    #[inline]
1002    pub unsafe fn cast<T>(self) -> MovingPtr<'a, T, A> {
1003        MovingPtr(self.0.cast::<T>(), PhantomData)
1004    }
1005
1006    /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
1007    ///
1008    /// # Safety
1009    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1010    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
1011    ///   for the pointee type `T`.
1012    ///
1013    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
1014    #[inline]
1015    pub unsafe fn drop_as<T>(self) {
1016        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
1017        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
1018        unsafe {
1019            ptr.drop_in_place();
1020        }
1021    }
1022
1023    /// Gets the underlying pointer, erasing the associated lifetime.
1024    ///
1025    /// If possible, it is strongly encouraged to use the other more type-safe functions
1026    /// over this function.
1027    #[inline]
1028    pub fn as_ptr(&self) -> *mut u8 {
1029        self.0.as_ptr()
1030    }
1031
1032    /// Gets an immutable pointer from this owned pointer.
1033    #[inline]
1034    pub fn as_ref(&self) -> Ptr<'_, A> {
1035        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
1036        unsafe { Ptr::new(self.0) }
1037    }
1038
1039    /// Gets a mutable pointer from this owned pointer.
1040    #[inline]
1041    pub fn as_mut(&mut self) -> PtrMut<'_, A> {
1042        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
1043        unsafe { PtrMut::new(self.0) }
1044    }
1045}
1046
1047impl<'a> OwningPtr<'a, Unaligned> {
1048    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
1049    ///
1050    /// # Safety
1051    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1052    pub unsafe fn read_unaligned<T>(self) -> T {
1053        let ptr = self.as_ptr().cast::<T>();
1054        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
1055        unsafe { ptr.read_unaligned() }
1056    }
1057}
1058
1059/// Conceptually equivalent to `&'a [T]` but with length information cut out for performance
1060/// reasons.
1061///
1062/// Because this type does not store the length of the slice, it is unable to do any sort of bounds
1063/// checking. As such, only [`Self::get_unchecked()`] is available for indexing into the slice,
1064/// where the user is responsible for checking the bounds.
1065///
1066/// When compiled in debug mode (`#[cfg(debug_assertion)]`), this type will store the length of the
1067/// slice and perform bounds checking in [`Self::get_unchecked()`].
1068///
1069/// # Example
1070///
1071/// ```
1072/// # use core::mem::size_of;
1073/// # use bevy_ptr::ThinSlicePtr;
1074/// #
1075/// let slice: &[u32] = &[2, 4, 8];
1076/// let thin_slice = ThinSlicePtr::from(slice);
1077///
1078/// assert_eq!(*unsafe { thin_slice.get_unchecked(0) }, 2);
1079/// assert_eq!(*unsafe { thin_slice.get_unchecked(1) }, 4);
1080/// assert_eq!(*unsafe { thin_slice.get_unchecked(2) }, 8);
1081/// ```
1082pub struct ThinSlicePtr<'a, T> {
1083    ptr: NonNull<T>,
1084    #[cfg(debug_assertions)]
1085    len: usize,
1086    _marker: PhantomData<&'a [T]>,
1087}
1088
1089impl<'a, T> ThinSlicePtr<'a, T> {
1090    /// Indexes the slice without performing bounds checks.
1091    ///
1092    /// # Safety
1093    ///
1094    /// `index` must be in-bounds.
1095    #[inline]
1096    pub unsafe fn get_unchecked(&self, index: usize) -> &'a T {
1097        // We cannot use `debug_assert!` here because `self.len` does not exist when not in debug
1098        // mode.
1099        #[cfg(debug_assertions)]
1100        if !(index < self.len) {
    {
        ::core::panicking::panic_fmt(format_args!("tried to index out-of-bounds of a slice"));
    }
};assert!(index < self.len, "tried to index out-of-bounds of a slice");
1101
1102        // SAFETY: The caller guarantees `index` is in-bounds so that the resulting pointer is
1103        // valid to dereference.
1104        unsafe { &*self.ptr.add(index).as_ptr() }
1105    }
1106
1107    /// Returns a slice without performing bounds checks.
1108    ///
1109    /// # Safety
1110    ///
1111    /// - There must be no mutable aliases for the lifetime `'a` to the slice. to the slice.
1112    /// - `len` must be less than or equal to the length of the slice.
1113    pub unsafe fn as_slice_unchecked(&self, len: usize) -> &'a [T] {
1114        #[cfg(debug_assertions)]
1115        if !(len <= self.len) {
    {
        ::core::panicking::panic_fmt(format_args!("tried to create an out-of-bounds slice"));
    }
};assert!(len <= self.len, "tried to create an out-of-bounds slice");
1116
1117        // SAFETY:
1118        // - The caller guarantees `len` is not greater than the length of the slice.
1119        // - The caller guarantees the aliasing rules.
1120        // - `self.ptr` is a valid pointer for the type `T`.
1121        // - `len` is valid hence `len * size_of::<T>()` is less than `isize::MAX`.
1122        unsafe { core::slice::from_raw_parts(self.ptr.as_ptr(), len) }
1123    }
1124
1125    /// Indexes the slice without performing bounds checks.
1126    ///
1127    /// # Safety
1128    ///
1129    /// `index` must be in-bounds.
1130    #[deprecated(since = "0.18.0", note = "use get_unchecked() instead")]
1131    pub unsafe fn get(self, index: usize) -> &'a T {
1132        // SAFETY: The caller guarantees that `index` is in-bounds.
1133        unsafe { self.get_unchecked(index) }
1134    }
1135}
1136
1137impl<'a, T> ThinSlicePtr<'a, UnsafeCell<T>> {
1138    /// Returns a mutable reference of the slice
1139    ///
1140    /// # Safety
1141    ///
1142    /// - There must not be any aliases for the lifetime `'a` to the slice.
1143    /// - `len` must be less than or equal to the length of the slice.
1144    pub unsafe fn as_mut_slice_unchecked(&self, len: usize) -> &'a mut [T] {
1145        #[cfg(debug_assertions)]
1146        if !(len <= self.len) {
    {
        ::core::panicking::panic_fmt(format_args!("tried to create an out-of-bounds slice"));
    }
};assert!(len <= self.len, "tried to create an out-of-bounds slice");
1147
1148        // SAFETY:
1149        // - The caller ensures no aliases exist and `len` is in-bounds.
1150        // - `self.ptr` is a valid pointer for the type `T`.
1151        // - `len` is valid hence `len * size_of::<T>()` is less than `isize::MAX`.
1152        unsafe { core::slice::from_raw_parts_mut(UnsafeCell::raw_get(self.ptr.as_ptr()), len) }
1153    }
1154
1155    /// Returns a slice pointer to the underlying type `T`.
1156    pub fn cast(&self) -> ThinSlicePtr<'a, T> {
1157        ThinSlicePtr {
1158            // SAFETY: `self.ptr` is non null hence `UnsafeCell::raw_get` always returns a non null pointer
1159            ptr: unsafe { NonNull::new_unchecked(UnsafeCell::raw_get(self.ptr.as_ptr())) },
1160            #[cfg(debug_assertions)]
1161            len: self.len,
1162            _marker: PhantomData,
1163        }
1164    }
1165}
1166
1167impl<'a, T> Clone for ThinSlicePtr<'a, T> {
1168    fn clone(&self) -> Self {
1169        *self
1170    }
1171}
1172
1173impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
1174
1175impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
1176    #[inline]
1177    fn from(slice: &'a [T]) -> Self {
1178        let ptr = slice.as_ptr().cast_mut().debug_ensure_aligned();
1179
1180        Self {
1181            // SAFETY: A reference can never be null.
1182            ptr: unsafe { NonNull::new_unchecked(ptr) },
1183            #[cfg(debug_assertions)]
1184            len: slice.len(),
1185            _marker: PhantomData,
1186        }
1187    }
1188}
1189
1190mod private {
1191    use core::cell::UnsafeCell;
1192
1193    pub trait SealedUnsafeCell {}
1194    impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
1195}
1196
1197/// Extension trait for helper methods on [`UnsafeCell`]
1198pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
1199    /// # Safety
1200    /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
1201    /// - 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).
1202    unsafe fn deref_mut(self) -> &'a mut T;
1203
1204    /// # Safety
1205    /// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
1206    /// - 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).
1207    unsafe fn deref(self) -> &'a T;
1208
1209    /// Returns a copy of the contained value.
1210    ///
1211    /// # Safety
1212    /// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
1213    /// - 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).
1214    unsafe fn read(self) -> T
1215    where
1216        T: Copy;
1217}
1218
1219impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
1220    #[inline]
1221    unsafe fn deref_mut(self) -> &'a mut T {
1222        // SAFETY: The caller upholds the alias rules.
1223        unsafe { &mut *self.get() }
1224    }
1225    #[inline]
1226    unsafe fn deref(self) -> &'a T {
1227        // SAFETY: The caller upholds the alias rules.
1228        unsafe { &*self.get() }
1229    }
1230
1231    #[inline]
1232    unsafe fn read(self) -> T
1233    where
1234        T: Copy,
1235    {
1236        // SAFETY: The caller upholds the alias rules.
1237        unsafe { self.get().read() }
1238    }
1239}
1240
1241trait DebugEnsureAligned {
1242    fn debug_ensure_aligned(self) -> Self;
1243}
1244
1245// Disable this for miri runs as it already checks if pointer to reference
1246// casts are properly aligned.
1247#[cfg(all(debug_assertions, not(miri)))]
1248impl<T: Sized> DebugEnsureAligned for *mut T {
1249    #[track_caller]
1250    fn debug_ensure_aligned(self) -> Self {
1251        if !self.is_aligned() {
    {
        ::core::panicking::panic_fmt(format_args!("pointer is not aligned. Address {0:p} does not have alignment {1} for type {2}",
                self, align_of::<T>(), core::any::type_name::<T>()));
    }
};assert!(
1252            self.is_aligned(),
1253            "pointer is not aligned. Address {:p} does not have alignment {} for type {}",
1254            self,
1255            align_of::<T>(),
1256            core::any::type_name::<T>()
1257        );
1258        self
1259    }
1260}
1261
1262#[cfg(any(not(debug_assertions), miri))]
1263impl<T: Sized> DebugEnsureAligned for *mut T {
1264    #[inline(always)]
1265    fn debug_ensure_aligned(self) -> Self {
1266        self
1267    }
1268}
1269
1270/// Safely converts a owned value into a [`MovingPtr`] while minimizing the number of stack copies.
1271///
1272/// This cannot be used as expression and must be used as a statement. Internally this macro works via variable shadowing.
1273#[macro_export]
1274macro_rules! move_as_ptr {
1275    ($value: ident) => {
1276        let mut $value = core::mem::MaybeUninit::new($value);
1277        // SAFETY:
1278        // - This macro shadows a MaybeUninit value that took ownership of the original value.
1279        //   it is impossible to refer to the original value, preventing further access after
1280        //   the `MovingPtr` has been used. `MaybeUninit` also prevents the compiler from
1281        //   dropping the original value.
1282        let $value = unsafe { $crate::MovingPtr::from_value(&mut $value) };
1283    };
1284}
1285
1286/// Helper macro used by [`deconstruct_moving_ptr`] to extract
1287/// the pattern from `field: pattern` or `field` shorthand.
1288#[macro_export]
1289#[doc(hidden)]
1290macro_rules! get_pattern {
1291    ($field_index:tt) => {
1292        $field_index
1293    };
1294    ($field_index:tt: $pattern:pat) => {
1295        $pattern
1296    };
1297}
1298
1299/// Deconstructs a [`MovingPtr`] into its individual fields.
1300///
1301/// This consumes the [`MovingPtr`] and hands out [`MovingPtr`] wrappers around
1302/// pointers to each of its fields. The value will *not* be dropped.
1303///
1304/// The macro should wrap a `let` expression with a struct pattern.
1305/// It does not support matching tuples by position,
1306/// so for tuple structs you should use `0: pat` syntax.
1307///
1308/// For tuples themselves, pass the identifier `tuple` instead of the struct name,
1309/// like `let tuple { 0: pat0, 1: pat1 } = value`.
1310///
1311/// This can also project into `MaybeUninit`.
1312/// Wrap the type name or `tuple` with `MaybeUninit::<_>`,
1313/// and the macro will deconstruct a `MovingPtr<MaybeUninit<ParentType>>`
1314/// into `MovingPtr<MaybeUninit<FieldType>>` values.
1315///
1316/// # Examples
1317///
1318/// ## Structs
1319///
1320/// ```
1321/// use core::mem::{offset_of, MaybeUninit};
1322/// use bevy_ptr::{MovingPtr, move_as_ptr};
1323/// # use bevy_ptr::Unaligned;
1324/// # struct FieldAType(usize);
1325/// # struct FieldBType(usize);
1326/// # struct FieldCType(usize);
1327///
1328/// # pub struct Parent {
1329/// #  pub field_a: FieldAType,
1330/// #  pub field_b: FieldBType,
1331/// #  pub field_c: FieldCType,
1332/// # }
1333///
1334/// let parent = Parent {
1335///   field_a: FieldAType(11),
1336///   field_b: FieldBType(22),
1337///   field_c: FieldCType(33),
1338/// };
1339///
1340/// let mut target_a = FieldAType(101);
1341/// let mut target_b = FieldBType(102);
1342/// let mut target_c = FieldCType(103);
1343///
1344/// // Converts `parent` into a `MovingPtr`
1345/// move_as_ptr!(parent);
1346///
1347/// // The field names must match the name used in the type definition.
1348/// // Each one will be a `MovingPtr` of the field's type.
1349/// bevy_ptr::deconstruct_moving_ptr!({
1350///   let Parent { field_a, field_b, field_c } = parent;
1351/// });
1352///
1353/// field_a.assign_to(&mut target_a);
1354/// field_b.assign_to(&mut target_b);
1355/// field_c.assign_to(&mut target_c);
1356///
1357/// assert_eq!(target_a.0, 11);
1358/// assert_eq!(target_b.0, 22);
1359/// assert_eq!(target_c.0, 33);
1360/// ```
1361///
1362/// ## Tuples
1363///
1364/// ```
1365/// use core::mem::{offset_of, MaybeUninit};
1366/// use bevy_ptr::{MovingPtr, move_as_ptr};
1367/// # use bevy_ptr::Unaligned;
1368/// # struct FieldAType(usize);
1369/// # struct FieldBType(usize);
1370/// # struct FieldCType(usize);
1371///
1372/// # pub struct Parent {
1373/// #   pub field_a: FieldAType,
1374/// #  pub field_b: FieldBType,
1375/// #  pub field_c: FieldCType,
1376/// # }
1377///
1378/// let parent = (
1379///   FieldAType(11),
1380///   FieldBType(22),
1381///   FieldCType(33),
1382/// );
1383///
1384/// let mut target_a = FieldAType(101);
1385/// let mut target_b = FieldBType(102);
1386/// let mut target_c = FieldCType(103);
1387///
1388/// // Converts `parent` into a `MovingPtr`
1389/// move_as_ptr!(parent);
1390///
1391/// // The field names must match the name used in the type definition.
1392/// // Each one will be a `MovingPtr` of the field's type.
1393/// bevy_ptr::deconstruct_moving_ptr!({
1394///   let tuple { 0: field_a, 1: field_b, 2: field_c } = parent;
1395/// });
1396///
1397/// field_a.assign_to(&mut target_a);
1398/// field_b.assign_to(&mut target_b);
1399/// field_c.assign_to(&mut target_c);
1400///
1401/// assert_eq!(target_a.0, 11);
1402/// assert_eq!(target_b.0, 22);
1403/// assert_eq!(target_c.0, 33);
1404/// ```
1405///
1406/// ## `MaybeUninit`
1407///
1408/// ```
1409/// use core::mem::{offset_of, MaybeUninit};
1410/// use bevy_ptr::{MovingPtr, move_as_ptr};
1411/// # use bevy_ptr::Unaligned;
1412/// # struct FieldAType(usize);
1413/// # struct FieldBType(usize);
1414/// # struct FieldCType(usize);
1415///
1416/// # pub struct Parent {
1417/// #  pub field_a: FieldAType,
1418/// #  pub field_b: FieldBType,
1419/// #  pub field_c: FieldCType,
1420/// # }
1421///
1422/// let parent = MaybeUninit::new(Parent {
1423///   field_a: FieldAType(11),
1424///   field_b: FieldBType(22),
1425///   field_c: FieldCType(33),
1426/// });
1427///
1428/// let mut target_a = MaybeUninit::new(FieldAType(101));
1429/// let mut target_b = MaybeUninit::new(FieldBType(102));
1430/// let mut target_c = MaybeUninit::new(FieldCType(103));
1431///
1432/// // Converts `parent` into a `MovingPtr`
1433/// move_as_ptr!(parent);
1434///
1435/// // The field names must match the name used in the type definition.
1436/// // Each one will be a `MovingPtr` of the field's type.
1437/// bevy_ptr::deconstruct_moving_ptr!({
1438///   let MaybeUninit::<Parent> { field_a, field_b, field_c } = parent;
1439/// });
1440///
1441/// field_a.assign_to(&mut target_a);
1442/// field_b.assign_to(&mut target_b);
1443/// field_c.assign_to(&mut target_c);
1444///
1445/// unsafe {
1446///   assert_eq!(target_a.assume_init().0, 11);
1447///   assert_eq!(target_b.assume_init().0, 22);
1448///   assert_eq!(target_c.assume_init().0, 33);
1449/// }
1450/// ```
1451///
1452/// [`assign_to`]: MovingPtr::assign_to
1453#[macro_export]
1454macro_rules! deconstruct_moving_ptr {
1455    ({ let tuple { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => {
1456        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1457        let mut ptr: $crate::MovingPtr<_, _> = $ptr;
1458        let _ = || {
1459            let value = &mut *ptr;
1460            // Ensure that each field index exists and is mentioned only once
1461            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1462            core::hint::black_box(($(&mut value.$field_index,)*));
1463            // Ensure that `ptr` is a tuple and not something that derefs to it
1464            // Ensure that the number of patterns matches the number of fields
1465            fn unreachable<T>(_index: usize) -> T {
1466                unreachable!()
1467            }
1468            *value = ($(unreachable($field_index),)*);
1469        };
1470        // SAFETY:
1471        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1472        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1473        // - `mem::forget` is called on `self` immediately after these calls
1474        // - Each field is distinct, since otherwise the block of code above would fail compilation
1475        $(let $pattern = unsafe { ptr.move_field(|f| &raw mut (*f).$field_index) };)*
1476        core::mem::forget(ptr);
1477    };
1478    ({ let MaybeUninit::<tuple> { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => {
1479        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1480        let mut ptr: $crate::MovingPtr<core::mem::MaybeUninit<_>, _> = $ptr;
1481        let _ = || {
1482            // SAFETY: This closure is never called
1483            let value = unsafe { ptr.assume_init_mut() };
1484            // Ensure that each field index exists and is mentioned only once
1485            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1486            core::hint::black_box(($(&mut value.$field_index,)*));
1487            // Ensure that `ptr` is a tuple and not something that derefs to it
1488            // Ensure that the number of patterns matches the number of fields
1489            fn unreachable<T>(_index: usize) -> T {
1490                unreachable!()
1491            }
1492            *value = ($(unreachable($field_index),)*);
1493        };
1494        // SAFETY:
1495        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1496        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1497        // - `mem::forget` is called on `self` immediately after these calls
1498        // - Each field is distinct, since otherwise the block of code above would fail compilation
1499        $(let $pattern = unsafe { ptr.move_maybe_uninit_field(|f| &raw mut (*f).$field_index) };)*
1500        core::mem::forget(ptr);
1501    };
1502    ({ let $struct_name:ident { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => {
1503        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1504        let mut ptr: $crate::MovingPtr<_, _> = $ptr;
1505        let _ = || {
1506            let value = &mut *ptr;
1507            // Ensure that each field index exists is mentioned only once
1508            // Ensure that each field is on the struct and not accessed using autoref
1509            let $struct_name { $($field_index: _),* } = value;
1510            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1511            core::hint::black_box(($(&mut value.$field_index),*));
1512            // Ensure that `ptr` is a `$struct_name` and not just something that derefs to it
1513            let value: *mut _ = value;
1514            // SAFETY: This closure is never called
1515            $struct_name { ..unsafe { value.read() } };
1516        };
1517        // SAFETY:
1518        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1519        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1520        // - `mem::forget` is called on `self` immediately after these calls
1521        // - Each field is distinct, since otherwise the block of code above would fail compilation
1522        $(let $crate::get_pattern!($field_index$(: $pattern)?) = unsafe { ptr.move_field(|f| &raw mut (*f).$field_index) };)*
1523        core::mem::forget(ptr);
1524    };
1525    ({ let MaybeUninit::<$struct_name:ident> { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => {
1526        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1527        let mut ptr: $crate::MovingPtr<core::mem::MaybeUninit<_>, _> = $ptr;
1528        let _ = || {
1529            // SAFETY: This closure is never called
1530            let value = unsafe { ptr.assume_init_mut() };
1531            // Ensure that each field index exists is mentioned only once
1532            // Ensure that each field is on the struct and not accessed using autoref
1533            let $struct_name { $($field_index: _),* } = value;
1534            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1535            core::hint::black_box(($(&mut value.$field_index),*));
1536            // Ensure that `ptr` is a `$struct_name` and not just something that derefs to it
1537            let value: *mut _ = value;
1538            // SAFETY: This closure is never called
1539            $struct_name { ..unsafe { value.read() } };
1540        };
1541        // SAFETY:
1542        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1543        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1544        // - `mem::forget` is called on `self` immediately after these calls
1545        // - Each field is distinct, since otherwise the block of code above would fail compilation
1546        $(let $crate::get_pattern!($field_index$(: $pattern)?) = unsafe { ptr.move_maybe_uninit_field(|f| &raw mut (*f).$field_index) };)*
1547        core::mem::forget(ptr);
1548    };
1549}