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 an 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, 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, Range},
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]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for Aligned {
}
#[automatically_derived]impl ::core::clone::Clone for Aligned {
    #[inline]
    fn clone(&self) -> Self { *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]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for Unaligned {
}
#[automatically_derived]impl ::core::clone::Clone for Unaligned {
    #[inline]
    fn clone(&self) -> Self { *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) -> Self {
        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 `core::ptr` 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 `core::ptr` 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) -> Self {
        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.0.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.0.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.0.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.0.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.0.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.0.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.0.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.0.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    ///  - The `dst` and the pointer `self` contains must not point at the same memory address.
579    ///
580    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
581    #[inline]
582    pub unsafe fn write_to(self, dst: *mut T) {
583        let src = self.0.as_ptr();
584        mem::forget(self);
585        // SAFETY:
586        //  - `src` must be valid for reads as this pointer is considered to own the value it points to.
587        //  - The caller is required to ensure that `dst` must be valid for writes.
588        //  - As `A` is `Aligned`, the caller is required to ensure that `dst` is aligned and `src` must
589        //    be aligned by the type's invariants.
590        //  - The caller is required to ensure that `dst` and `src` do not point to the same memory address.
591        //  - We took self by move and forgotten it, so nothing else can observe `src` being moved out.
592        unsafe { A::copy_nonoverlapping(src, dst, 1) };
593    }
594
595    /// Writes the value pointed to by this pointer into `dst`.
596    ///
597    /// The value previously stored at `dst` will be dropped.
598    ///
599    /// This has the same semantics as a normal `*dst = ...` assignment.
600    #[inline]
601    pub fn assign_to(self, dst: &mut T) {
602        // This code has the same semantics as the following:
603        // ```
604        // let src = self.0.as_ptr();
605        // mem::forget(self);
606        // *dst = unsafe { A::read(src) };
607        // ```
608        //
609        // However the above might codegen to multiple `memcpy`s, while the code below will avoid that.
610
611        struct DropGuard<'a, 'b, T, A: IsAligned> {
612            src: ManuallyDrop<MovingPtr<'a, T, A>>,
613            dst: &'b mut T,
614        }
615
616        impl<'a, 'b, T, A: IsAligned> Drop for DropGuard<'a, 'b, T, A> {
617            fn drop(&mut self) {
618                // SAFETY: `self.src` is always initialized with a valid `MovingPtr` and is only ever taken here
619                // in drop. No other code can observe the invalid `self.src` after this point.
620                let src = unsafe { ManuallyDrop::take(&mut self.src) };
621
622                // SAFETY:
623                // - `dst` is a mutable borrow, it must be valid for writes.
624                // - `dst` is a mutable borrow, it must always be aligned.
625                unsafe { src.write_to(self.dst) };
626            }
627        }
628
629        let guard = DropGuard {
630            src: ManuallyDrop::new(self),
631            dst,
632        };
633
634        // SAFETY:
635        // - `guard.dst` is a mutable borrow, it must point to a valid instance of `T`.
636        // - `guard.dst` is a mutable borrow, it must point to value that is valid for dropping.
637        // - `guard.dst` is a mutable borrow, it must not alias any other access.
638        // - `guard.dst` will be overwritten when `guard` is dropped, so no other code can observe it being dropped.
639        unsafe {
640            ptr::drop_in_place(guard.dst);
641        }
642    }
643
644    /// Creates a [`MovingPtr`] for a specific field within `self`.
645    ///
646    /// This function is explicitly made for deconstructive moves.
647    ///
648    /// The correct `byte_offset` for a field can be obtained via [`core::mem::offset_of`].
649    ///
650    /// # Safety
651    ///  - `f` must return a non-null pointer to a valid field inside `T`
652    ///  - If `A` is [`Aligned`], then `T` must not be `repr(packed)`
653    ///  - `self` should not be accessed or dropped as if it were a complete value after this function returns.
654    ///    Other fields that have not been moved out of may still be accessed or dropped separately.
655    ///  - This function cannot alias the field with any other access, including other calls to [`move_field`]
656    ///    for the same field, without first calling [`forget`] on it first.
657    ///
658    /// A result of the above invariants means that any operation that could cause `self` to be dropped while
659    /// the pointers to the fields are held will result in undefined behavior. This requires extra caution
660    /// around code that may panic. See the example below for an example of how to safely use this function.
661    ///
662    /// # Example
663    ///
664    /// ```
665    /// use core::mem::offset_of;
666    /// use bevy_ptr::{MovingPtr, move_as_ptr};
667    /// # struct FieldAType(usize);
668    /// # struct FieldBType(usize);
669    /// # struct FieldCType(usize);
670    /// # fn insert<T>(_ptr: MovingPtr<'_, T>) {}
671    ///
672    /// struct Parent {
673    ///   field_a: FieldAType,
674    ///   field_b: FieldBType,
675    ///   field_c: FieldCType,
676    /// }
677    ///
678    /// let parent = Parent {
679    ///    field_a: FieldAType(0),
680    ///    field_b: FieldBType(0),
681    ///    field_c: FieldCType(0),
682    /// };
683    ///
684    /// // Converts `parent` into a `MovingPtr`.
685    /// move_as_ptr!(parent);
686    ///
687    /// unsafe {
688    ///    let field_a = parent.move_field(|ptr| &raw mut (*ptr).field_a);
689    ///    let field_b = parent.move_field(|ptr| &raw mut (*ptr).field_b);
690    ///    let field_c = parent.move_field(|ptr| &raw mut (*ptr).field_c);
691    ///    // Each call to insert may panic! Ensure that `parent_ptr` cannot be dropped before
692    ///    // calling them!
693    ///    core::mem::forget(parent);
694    ///    insert(field_a);
695    ///    insert(field_b);
696    ///    insert(field_c);
697    /// }
698    /// ```
699    ///
700    /// [`forget`]: core::mem::forget
701    /// [`move_field`]: Self::move_field
702    #[inline(always)]
703    pub unsafe fn move_field<U>(&self, f: impl Fn(*mut T) -> *mut U) -> MovingPtr<'a, U, A> {
704        MovingPtr(
705            // SAFETY: The caller must ensure that `U` is the correct type for the field at `byte_offset`.
706            unsafe { NonNull::new_unchecked(f(self.0.as_ptr())) },
707            PhantomData,
708        )
709    }
710}
711
712impl<'a, T, A: IsAligned> MovingPtr<'a, MaybeUninit<T>, A> {
713    /// Creates a [`MovingPtr`] for a specific field within `self`.
714    ///
715    /// This function is explicitly made for deconstructive moves.
716    ///
717    /// The correct `byte_offset` for a field can be obtained via [`core::mem::offset_of`].
718    ///
719    /// # Safety
720    ///  - `f` must return a non-null pointer to a valid field inside `T`
721    ///  - If `A` is [`Aligned`], then `T` must not be `repr(packed)`
722    ///  - `self` should not be accessed or dropped as if it were a complete value after this function returns.
723    ///    Other fields that have not been moved out of may still be accessed or dropped separately.
724    ///  - This function cannot alias the field with any other access, including other calls to [`move_field`]
725    ///    for the same field, without first calling [`forget`] on it first.
726    ///
727    /// [`forget`]: core::mem::forget
728    /// [`move_field`]: Self::move_field
729    #[inline(always)]
730    pub unsafe fn move_maybe_uninit_field<U>(
731        &self,
732        f: impl Fn(*mut T) -> *mut U,
733    ) -> MovingPtr<'a, MaybeUninit<U>, A> {
734        let self_ptr = self.0.as_ptr().cast::<T>();
735        // SAFETY:
736        // - The caller must ensure that `U` is the correct type for the field at `byte_offset` and thus
737        //   cannot be null.
738        // - `MaybeUninit<T>` is `repr(transparent)` and thus must have the same memory layout as `T``
739        let field_ptr = unsafe { NonNull::new_unchecked(f(self_ptr)) };
740        MovingPtr(field_ptr.cast::<MaybeUninit<U>>(), PhantomData)
741    }
742}
743
744impl<'a, T, A: IsAligned> MovingPtr<'a, MaybeUninit<T>, A> {
745    /// Creates a [`MovingPtr`] pointing to a valid instance of `T`.
746    ///
747    /// See also: [`MaybeUninit::assume_init`].
748    ///
749    /// # Safety
750    /// It's up to the caller to ensure that the value pointed to by `self`
751    /// is really in an initialized state. Calling this when the content is not yet
752    /// fully initialized causes immediate undefined behavior.
753    #[inline]
754    pub unsafe fn assume_init(self) -> MovingPtr<'a, T, A> {
755        let value = MovingPtr(self.0.cast::<T>(), PhantomData);
756        mem::forget(self);
757        value
758    }
759}
760
761impl<T, A: IsAligned> Pointer for MovingPtr<'_, T, A> {
762    #[inline]
763    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
764        Pointer::fmt(&self.0, f)
765    }
766}
767
768impl<T> Debug for MovingPtr<'_, T, Aligned> {
769    #[inline]
770    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
771        f.write_fmt(format_args!("MovingPtr<Aligned>({0:?})", self.0))write!(f, "MovingPtr<Aligned>({:?})", self.0)
772    }
773}
774
775impl<T> Debug for MovingPtr<'_, T, Unaligned> {
776    #[inline]
777    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
778        f.write_fmt(format_args!("MovingPtr<Unaligned>({0:?})", self.0))write!(f, "MovingPtr<Unaligned>({:?})", self.0)
779    }
780}
781
782impl<'a, T, A: IsAligned> From<MovingPtr<'a, T, A>> for OwningPtr<'a, A> {
783    #[inline]
784    fn from(value: MovingPtr<'a, T, A>) -> Self {
785        // SAFETY:
786        // - `value.0` must always point to valid value of type `T`.
787        // - The type parameter `A` is mirrored from input to output, keeping the same alignment guarantees.
788        // - `value.0` by construction must have correct provenance to allow read and writes of type `T`.
789        // - The lifetime `'a` is mirrored from input to output, keeping the same lifetime guarantees.
790        // - `OwningPtr` maintains the same aliasing invariants as `MovingPtr`.
791        let ptr = unsafe { OwningPtr::new(value.0.cast::<u8>()) };
792        mem::forget(value);
793        ptr
794    }
795}
796
797impl<'a, T> TryFrom<MovingPtr<'a, T, Unaligned>> for MovingPtr<'a, T, Aligned> {
798    type Error = MovingPtr<'a, T, Unaligned>;
799    #[inline]
800    fn try_from(value: MovingPtr<'a, T, Unaligned>) -> Result<Self, Self::Error> {
801        let ptr = value.0;
802        if ptr.as_ptr().is_aligned() {
803            mem::forget(value);
804            Ok(MovingPtr(ptr, PhantomData))
805        } else {
806            Err(value)
807        }
808    }
809}
810
811impl<T> Deref for MovingPtr<'_, T, Aligned> {
812    type Target = T;
813    #[inline]
814    fn deref(&self) -> &Self::Target {
815        let ptr = self.0.as_ptr().debug_ensure_aligned();
816        // SAFETY: This type owns the value it points to and the generic type parameter is `A` so this pointer must be aligned.
817        unsafe { &*ptr }
818    }
819}
820
821impl<T> DerefMut for MovingPtr<'_, T, Aligned> {
822    #[inline]
823    fn deref_mut(&mut self) -> &mut Self::Target {
824        let ptr = self.0.as_ptr().debug_ensure_aligned();
825        // SAFETY: This type owns the value it points to and the generic type parameter is `A` so this pointer must be aligned.
826        unsafe { &mut *ptr }
827    }
828}
829
830impl<T, A: IsAligned> Drop for MovingPtr<'_, T, A> {
831    fn drop(&mut self) {
832        // SAFETY:
833        //  - `self.0` must be valid for reads and writes as this pointer type owns the value it points to.
834        //  - `self.0` must always point to a valid instance of type `T`
835        //  - If `A` is `Aligned`, then `ptr` must be properly aligned for type `T` by construction.
836        //  - `self.0` owns the value it points to so it must always be valid for dropping until this pointer is dropped.
837        //  - This type owns the value it points to, so it's required to not mutably alias value that it points to.
838        unsafe { A::drop_in_place(self.0.as_ptr()) };
839    }
840}
841
842impl<'a, A: IsAligned> Ptr<'a, A> {
843    /// Creates a new instance from a raw pointer.
844    ///
845    /// # Safety
846    /// - `inner` must point to valid value of whatever the pointee type is.
847    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
848    /// - `inner` must have correct provenance to allow reads of the pointee type.
849    /// - The lifetime `'a` must be constrained such that this [`Ptr`] will stay valid and nothing
850    ///   can mutate the pointee while this [`Ptr`] is live except through an [`UnsafeCell`].
851    ///
852    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
853    #[inline]
854    pub unsafe fn new(inner: NonNull<u8>) -> Self {
855        Self(inner, PhantomData)
856    }
857
858    /// Transforms this [`Ptr`] into an [`PtrMut`]
859    ///
860    /// # Safety
861    /// * The data pointed to by this `Ptr` must be valid for writes.
862    /// * There must be no active references (mutable or otherwise) to the data underlying this `Ptr`.
863    /// * Another [`PtrMut`] for the same [`Ptr`] must not be created until the first is dropped.
864    #[inline]
865    pub unsafe fn assert_unique(self) -> PtrMut<'a, A> {
866        PtrMut(self.0, PhantomData)
867    }
868
869    /// Transforms this [`Ptr<T>`] into a `&T` with the same lifetime
870    ///
871    /// # Safety
872    /// - `T` must be the erased pointee type for this [`Ptr`].
873    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
874    ///   for the pointee type `T`.
875    ///
876    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
877    #[inline]
878    pub unsafe fn deref<T>(self) -> &'a T {
879        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
880        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
881        unsafe { &*ptr }
882    }
883
884    /// Gets the underlying pointer, erasing the associated lifetime.
885    ///
886    /// If possible, it is strongly encouraged to use [`deref`](Self::deref) over this function,
887    /// as it retains the lifetime.
888    #[inline]
889    pub fn as_ptr(self) -> *const u8 {
890        self.0.as_ptr().cast_const()
891    }
892}
893
894impl<'a, T: ?Sized> From<&'a T> for Ptr<'a> {
895    #[inline]
896    fn from(val: &'a T) -> Self {
897        // SAFETY: The returned pointer has the same lifetime as the passed reference.
898        // Access is immutable.
899        unsafe { Self::new(NonNull::from(val).cast()) }
900    }
901}
902
903impl<'a, A: IsAligned> PtrMut<'a, A> {
904    /// Creates a new instance from a raw pointer.
905    ///
906    /// # Safety
907    /// - `inner` must point to valid value of whatever the pointee type is.
908    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
909    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
910    /// - The lifetime `'a` must be constrained such that this [`PtrMut`] will stay valid and nothing
911    ///   else can read or mutate the pointee while this [`PtrMut`] is live.
912    ///
913    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
914    #[inline]
915    pub unsafe fn new(inner: NonNull<u8>) -> Self {
916        Self(inner, PhantomData)
917    }
918
919    /// Transforms this [`PtrMut`] into an [`OwningPtr`]
920    ///
921    /// # Safety
922    /// Must have right to drop or move out of [`PtrMut`].
923    #[inline]
924    pub unsafe fn promote(self) -> OwningPtr<'a, A> {
925        OwningPtr(self.0, PhantomData)
926    }
927
928    /// Transforms this [`PtrMut<T>`] into a `&mut T` with the same lifetime
929    ///
930    /// # Safety
931    /// - `T` must be the erased pointee type for this [`PtrMut`].
932    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
933    ///   for the pointee type `T`.
934    ///
935    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
936    #[inline]
937    pub unsafe fn deref_mut<T>(self) -> &'a mut T {
938        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
939        // SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
940        unsafe { &mut *ptr }
941    }
942
943    /// Gets the underlying pointer, erasing the associated lifetime.
944    ///
945    /// If possible, it is strongly encouraged to use [`deref_mut`](Self::deref_mut) over
946    /// this function, as it retains the lifetime.
947    #[inline]
948    pub fn as_ptr(&self) -> *mut u8 {
949        self.0.as_ptr()
950    }
951
952    /// Gets a [`PtrMut`] from this with a smaller lifetime.
953    #[inline]
954    pub fn reborrow(&mut self) -> PtrMut<'_, A> {
955        // SAFETY: the ptrmut we're borrowing from is assumed to be valid
956        unsafe { PtrMut::new(self.0) }
957    }
958
959    /// Gets an immutable reference from this mutable reference
960    #[inline]
961    pub fn as_ref(&self) -> Ptr<'_, A> {
962        // SAFETY: The `PtrMut` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
963        unsafe { Ptr::new(self.0) }
964    }
965}
966
967impl<'a, T: ?Sized> From<&'a mut T> for PtrMut<'a> {
968    #[inline]
969    fn from(val: &'a mut T) -> Self {
970        // SAFETY: The returned pointer has the same lifetime as the passed reference.
971        // The reference is mutable, and thus will not alias.
972        unsafe { Self::new(NonNull::from(val).cast()) }
973    }
974}
975
976impl<'a> OwningPtr<'a> {
977    /// This exists mostly to reduce compile times;
978    /// code is only duplicated per type, rather than per function called.
979    ///
980    /// # Safety
981    ///
982    /// Safety constraints of [`PtrMut::promote`] must be upheld.
983    unsafe fn make_internal<T>(temp: &mut ManuallyDrop<T>) -> OwningPtr<'_> {
984        // SAFETY: The constraints of `promote` are upheld by caller.
985        unsafe { PtrMut::from(&mut *temp).promote() }
986    }
987
988    /// Consumes a value and creates an [`OwningPtr`] to it while ensuring a double drop does not happen.
989    #[inline]
990    pub fn make<T, F: FnOnce(OwningPtr<'_>) -> R, R>(val: T, f: F) -> R {
991        let mut val = ManuallyDrop::new(val);
992        // SAFETY: The value behind the pointer will not get dropped or observed later,
993        // so it's safe to promote it to an owning pointer.
994        f(unsafe { Self::make_internal(&mut val) })
995    }
996}
997
998impl<'a, A: IsAligned> OwningPtr<'a, A> {
999    /// Creates a new instance from a raw pointer.
1000    ///
1001    /// # Safety
1002    /// - `inner` must point to valid value of whatever the pointee type is.
1003    /// - If the `A` type parameter is [`Aligned`] then `inner` must be [properly aligned] for the pointee type.
1004    /// - `inner` must have correct provenance to allow read and writes of the pointee type.
1005    /// - The lifetime `'a` must be constrained such that this [`OwningPtr`] will stay valid and nothing
1006    ///   else can read or mutate the pointee while this [`OwningPtr`] is live.
1007    ///
1008    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
1009    #[inline]
1010    pub unsafe fn new(inner: NonNull<u8>) -> Self {
1011        Self(inner, PhantomData)
1012    }
1013
1014    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
1015    ///
1016    /// # Safety
1017    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1018    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
1019    ///   for the pointee type `T`.
1020    ///
1021    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
1022    #[inline]
1023    pub unsafe fn read<T>(self) -> T {
1024        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
1025        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
1026        unsafe { ptr.read() }
1027    }
1028
1029    /// Casts to a concrete type as a [`MovingPtr`].
1030    ///
1031    /// # Safety
1032    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1033    #[inline]
1034    pub unsafe fn cast<T>(self) -> MovingPtr<'a, T, A> {
1035        MovingPtr(self.0.cast::<T>(), PhantomData)
1036    }
1037
1038    /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
1039    ///
1040    /// # Safety
1041    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1042    /// - If the type parameter `A` is [`Unaligned`] then this pointer must be [properly aligned]
1043    ///   for the pointee type `T`.
1044    ///
1045    /// [properly aligned]: https://doc.rust-lang.org/std/ptr/index.html#alignment
1046    #[inline]
1047    pub unsafe fn drop_as<T>(self) {
1048        let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
1049        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
1050        unsafe {
1051            ptr.drop_in_place();
1052        }
1053    }
1054
1055    /// Gets the underlying pointer, erasing the associated lifetime.
1056    ///
1057    /// If possible, it is strongly encouraged to use the other more type-safe functions
1058    /// over this function.
1059    #[inline]
1060    pub fn as_ptr(&self) -> *mut u8 {
1061        self.0.as_ptr()
1062    }
1063
1064    /// Gets an immutable pointer from this owned pointer.
1065    #[inline]
1066    pub fn as_ref(&self) -> Ptr<'_, A> {
1067        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
1068        unsafe { Ptr::new(self.0) }
1069    }
1070
1071    /// Gets a mutable pointer from this owned pointer.
1072    #[inline]
1073    pub fn as_mut(&mut self) -> PtrMut<'_, A> {
1074        // SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
1075        unsafe { PtrMut::new(self.0) }
1076    }
1077}
1078
1079impl<'a> OwningPtr<'a, Unaligned> {
1080    /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
1081    ///
1082    /// # Safety
1083    /// - `T` must be the erased pointee type for this [`OwningPtr`].
1084    pub unsafe fn read_unaligned<T>(self) -> T {
1085        let ptr = self.as_ptr().cast::<T>();
1086        // SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
1087        unsafe { ptr.read_unaligned() }
1088    }
1089}
1090
1091/// Conceptually equivalent to `&'a [T]` but with length information cut out for performance
1092/// reasons.
1093///
1094/// Because this type does not store the length of the slice, it is unable to do any sort of bounds
1095/// checking. As such, only [`Self::get_unchecked()`] is available for indexing into the slice,
1096/// where the user is responsible for checking the bounds.
1097///
1098/// When compiled in debug mode (`#[cfg(debug_assertion)]`), this type will store the length of the
1099/// slice and perform bounds checking in [`Self::get_unchecked()`].
1100///
1101/// # Example
1102///
1103/// ```
1104/// # use core::mem::size_of;
1105/// # use bevy_ptr::ThinSlicePtr;
1106/// #
1107/// let slice: &[u32] = &[2, 4, 8];
1108/// let thin_slice = ThinSlicePtr::from(slice);
1109///
1110/// assert_eq!(*unsafe { thin_slice.get_unchecked(0) }, 2);
1111/// assert_eq!(*unsafe { thin_slice.get_unchecked(1) }, 4);
1112/// assert_eq!(*unsafe { thin_slice.get_unchecked(2) }, 8);
1113/// ```
1114pub struct ThinSlicePtr<'a, T> {
1115    ptr: NonNull<T>,
1116    #[cfg(debug_assertions)]
1117    len: usize,
1118    _marker: PhantomData<&'a [T]>,
1119}
1120
1121impl<'a, T> ThinSlicePtr<'a, T> {
1122    /// Indexes the slice without performing bounds checks.
1123    ///
1124    /// # Safety
1125    ///
1126    /// `index` must be in-bounds.
1127    #[inline]
1128    pub unsafe fn get_unchecked(&self, index: usize) -> &'a T {
1129        // We cannot use `debug_assert!` here because `self.len` does not exist when not in debug
1130        // mode.
1131        #[cfg(debug_assertions)]
1132        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");
1133
1134        // SAFETY: The caller guarantees `index` is in-bounds so that the resulting pointer is
1135        // valid to dereference.
1136        unsafe { &*self.ptr.add(index).as_ptr() }
1137    }
1138
1139    /// Returns a slice without performing bounds checks.
1140    ///
1141    /// # Safety
1142    ///
1143    /// - There must be no mutable aliases for the lifetime `'a` to the slice. to the slice.
1144    /// - `len` must be less than or equal to the length of the slice.
1145    pub unsafe fn as_slice_unchecked(&self, len: usize) -> &'a [T] {
1146        #[cfg(debug_assertions)]
1147        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");
1148
1149        // SAFETY:
1150        // - The caller guarantees `len` is not greater than the length of the slice.
1151        // - The caller guarantees the aliasing rules.
1152        // - `self.ptr` is a valid pointer for the type `T`.
1153        // - `len` is valid hence `len * size_of::<T>()` is less than `isize::MAX`.
1154        unsafe { core::slice::from_raw_parts(self.ptr.as_ptr(), len) }
1155    }
1156
1157    /// Returns a subslice without performing bounds checks.
1158    ///
1159    /// # Safety
1160    ///
1161    /// - There must be no mutable aliases for the lifetime `'a` to the slice.
1162    /// - `range.start` and `range.end` must be less than or equal to the length of the slice.
1163    /// - `range.start` must be less than or equal to `range.end`.
1164    pub unsafe fn slice_unchecked(&self, range: Range<usize>) -> &'a [T] {
1165        // SAFETY: The caller guarantees that `range` is within range of the slice.
1166        unsafe {
1167            core::slice::from_raw_parts(self.ptr.as_ptr().add(range.start), range.end - range.start)
1168        }
1169    }
1170}
1171
1172impl<'a, T> ThinSlicePtr<'a, UnsafeCell<T>> {
1173    /// Returns a mutable reference of the slice
1174    ///
1175    /// # Safety
1176    ///
1177    /// - There must not be any aliases for the lifetime `'a` to the slice.
1178    /// - `len` must be less than or equal to the length of the slice.
1179    pub unsafe fn as_mut_slice_unchecked(&self, len: usize) -> &'a mut [T] {
1180        #[cfg(debug_assertions)]
1181        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");
1182
1183        // SAFETY:
1184        // - The caller ensures no aliases exist and `len` is in-bounds.
1185        // - `self.ptr` is a valid pointer for the type `T`.
1186        // - `len` is valid hence `len * size_of::<T>()` is less than `isize::MAX`.
1187        unsafe { core::slice::from_raw_parts_mut(UnsafeCell::raw_get(self.ptr.as_ptr()), len) }
1188    }
1189
1190    /// Returns a mutable subslice of the slice.
1191    ///
1192    /// # Safety
1193    ///
1194    /// - There must not be any aliases for the lifetime `'a` to the slice.
1195    /// - `range.start` and `range.end` must be less than or equal to the length of the slice.
1196    /// - `range.start` must be less than or equal to `range.end`.
1197    pub unsafe fn slice_mut_unchecked(&self, range: Range<usize>) -> &'a mut [T] {
1198        // SAFETY: The caller guarantees that `range` is within range of the slice.
1199        unsafe {
1200            core::slice::from_raw_parts_mut(
1201                UnsafeCell::raw_get(self.ptr.as_ptr().add(range.start)),
1202                range.end - range.start,
1203            )
1204        }
1205    }
1206
1207    /// Returns a slice pointer to the underlying type `T`.
1208    pub fn cast(&self) -> ThinSlicePtr<'a, T> {
1209        ThinSlicePtr {
1210            // SAFETY: `self.ptr` is non null hence `UnsafeCell::raw_get` always returns a non null pointer
1211            ptr: unsafe { NonNull::new_unchecked(UnsafeCell::raw_get(self.ptr.as_ptr())) },
1212            #[cfg(debug_assertions)]
1213            len: self.len,
1214            _marker: PhantomData,
1215        }
1216    }
1217}
1218
1219impl<'a, T> Clone for ThinSlicePtr<'a, T> {
1220    fn clone(&self) -> Self {
1221        *self
1222    }
1223}
1224
1225impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
1226
1227impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
1228    #[inline]
1229    fn from(slice: &'a [T]) -> Self {
1230        let ptr = slice.as_ptr().cast_mut().debug_ensure_aligned();
1231
1232        Self {
1233            // SAFETY: A reference can never be null.
1234            ptr: unsafe { NonNull::new_unchecked(ptr) },
1235            #[cfg(debug_assertions)]
1236            len: slice.len(),
1237            _marker: PhantomData,
1238        }
1239    }
1240}
1241
1242mod private {
1243    use core::cell::UnsafeCell;
1244
1245    pub trait SealedUnsafeCell {}
1246    impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
1247}
1248
1249/// Extension trait for helper methods on [`UnsafeCell`]
1250pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
1251    /// # Safety
1252    /// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
1253    /// - 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).
1254    unsafe fn deref_mut(self) -> &'a mut T;
1255
1256    /// # Safety
1257    /// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
1258    /// - 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).
1259    unsafe fn deref(self) -> &'a T;
1260
1261    /// Returns a copy of the contained value.
1262    ///
1263    /// # Safety
1264    /// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
1265    /// - 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).
1266    unsafe fn read(self) -> T
1267    where
1268        T: Copy;
1269}
1270
1271impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
1272    #[inline]
1273    unsafe fn deref_mut(self) -> &'a mut T {
1274        // SAFETY: The caller upholds the alias rules.
1275        unsafe { &mut *self.get() }
1276    }
1277    #[inline]
1278    unsafe fn deref(self) -> &'a T {
1279        // SAFETY: The caller upholds the alias rules.
1280        unsafe { &*self.get() }
1281    }
1282
1283    #[inline]
1284    unsafe fn read(self) -> T
1285    where
1286        T: Copy,
1287    {
1288        // SAFETY: The caller upholds the alias rules.
1289        unsafe { self.get().read() }
1290    }
1291}
1292
1293trait DebugEnsureAligned {
1294    fn debug_ensure_aligned(self) -> Self;
1295}
1296
1297// Disable this for miri runs as it already checks if pointer to reference
1298// casts are properly aligned.
1299#[cfg(all(debug_assertions, not(miri)))]
1300impl<T: Sized> DebugEnsureAligned for *mut T {
1301    #[track_caller]
1302    fn debug_ensure_aligned(self) -> Self {
1303        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!(
1304            self.is_aligned(),
1305            "pointer is not aligned. Address {:p} does not have alignment {} for type {}",
1306            self,
1307            align_of::<T>(),
1308            core::any::type_name::<T>()
1309        );
1310        self
1311    }
1312}
1313
1314#[cfg(any(not(debug_assertions), miri))]
1315impl<T: Sized> DebugEnsureAligned for *mut T {
1316    #[inline(always)]
1317    fn debug_ensure_aligned(self) -> Self {
1318        self
1319    }
1320}
1321
1322// Same as above, but for *const T.
1323#[cfg(all(debug_assertions, not(miri)))]
1324impl<T: Sized> DebugEnsureAligned for *const T {
1325    #[track_caller]
1326    fn debug_ensure_aligned(self) -> Self {
1327        // Call into the *mut version.
1328        self.cast_mut().debug_ensure_aligned();
1329        self
1330    }
1331}
1332
1333#[cfg(any(not(debug_assertions), miri))]
1334impl<T: Sized> DebugEnsureAligned for *const T {
1335    #[inline(always)]
1336    fn debug_ensure_aligned(self) -> Self {
1337        self
1338    }
1339}
1340
1341/// Safely converts a owned value into a [`MovingPtr`] while minimizing the number of stack copies.
1342///
1343/// This cannot be used as expression and must be used as a statement. Internally this macro works via variable shadowing.
1344#[macro_export]
1345macro_rules! move_as_ptr {
1346    ($value: ident) => {
1347        let mut $value = ::core::mem::MaybeUninit::new($value);
1348        // SAFETY:
1349        // - This macro shadows a MaybeUninit value that took ownership of the original value.
1350        //   it is impossible to refer to the original value, preventing further access after
1351        //   the `MovingPtr` has been used. `MaybeUninit` also prevents the compiler from
1352        //   dropping the original value.
1353        let $value = unsafe { $crate::MovingPtr::from_value(&mut $value) };
1354    };
1355}
1356
1357/// Helper macro used by [`deconstruct_moving_ptr`] to extract
1358/// the pattern from `field: pattern` or `field` shorthand.
1359#[macro_export]
1360#[doc(hidden)]
1361macro_rules! get_pattern {
1362    ($field_index:tt) => {
1363        $field_index
1364    };
1365    ($field_index:tt: $pattern:pat) => {
1366        $pattern
1367    };
1368}
1369
1370/// Deconstructs a [`MovingPtr`] into its individual fields.
1371///
1372/// This consumes the [`MovingPtr`] and hands out [`MovingPtr`] wrappers around
1373/// pointers to each of its fields. The value will *not* be dropped.
1374///
1375/// The macro should wrap a `let` expression with a struct pattern.
1376/// It does not support matching tuples by position,
1377/// so for tuple structs you should use `0: pat` syntax.
1378///
1379/// For tuples themselves, pass the identifier `tuple` instead of the struct name,
1380/// like `let tuple { 0: pat0, 1: pat1 } = value`.
1381///
1382/// This can also project into `MaybeUninit`.
1383/// Wrap the type name or `tuple` with `MaybeUninit::<_>`,
1384/// and the macro will deconstruct a `MovingPtr<MaybeUninit<ParentType>>`
1385/// into `MovingPtr<MaybeUninit<FieldType>>` values.
1386///
1387/// # Examples
1388///
1389/// ## Structs
1390///
1391/// ```
1392/// use core::mem::{offset_of, MaybeUninit};
1393/// use bevy_ptr::{MovingPtr, move_as_ptr};
1394/// # use bevy_ptr::Unaligned;
1395/// # struct FieldAType(usize);
1396/// # struct FieldBType(usize);
1397/// # struct FieldCType(usize);
1398///
1399/// # pub struct Parent {
1400/// #  pub field_a: FieldAType,
1401/// #  pub field_b: FieldBType,
1402/// #  pub field_c: FieldCType,
1403/// # }
1404///
1405/// let parent = Parent {
1406///   field_a: FieldAType(11),
1407///   field_b: FieldBType(22),
1408///   field_c: FieldCType(33),
1409/// };
1410///
1411/// let mut target_a = FieldAType(101);
1412/// let mut target_b = FieldBType(102);
1413/// let mut target_c = FieldCType(103);
1414///
1415/// // Converts `parent` into a `MovingPtr`
1416/// move_as_ptr!(parent);
1417///
1418/// // The field names must match the name used in the type definition.
1419/// // Each one will be a `MovingPtr` of the field's type.
1420/// bevy_ptr::deconstruct_moving_ptr!({
1421///   let Parent { field_a, field_b, field_c } = parent;
1422/// });
1423///
1424/// field_a.assign_to(&mut target_a);
1425/// field_b.assign_to(&mut target_b);
1426/// field_c.assign_to(&mut target_c);
1427///
1428/// assert_eq!(target_a.0, 11);
1429/// assert_eq!(target_b.0, 22);
1430/// assert_eq!(target_c.0, 33);
1431/// ```
1432///
1433/// ## Tuples
1434///
1435/// ```
1436/// use core::mem::{offset_of, MaybeUninit};
1437/// use bevy_ptr::{MovingPtr, move_as_ptr};
1438/// # use bevy_ptr::Unaligned;
1439/// # struct FieldAType(usize);
1440/// # struct FieldBType(usize);
1441/// # struct FieldCType(usize);
1442///
1443/// # pub struct Parent {
1444/// #   pub field_a: FieldAType,
1445/// #  pub field_b: FieldBType,
1446/// #  pub field_c: FieldCType,
1447/// # }
1448///
1449/// let parent = (
1450///   FieldAType(11),
1451///   FieldBType(22),
1452///   FieldCType(33),
1453/// );
1454///
1455/// let mut target_a = FieldAType(101);
1456/// let mut target_b = FieldBType(102);
1457/// let mut target_c = FieldCType(103);
1458///
1459/// // Converts `parent` into a `MovingPtr`
1460/// move_as_ptr!(parent);
1461///
1462/// // The field names must match the name used in the type definition.
1463/// // Each one will be a `MovingPtr` of the field's type.
1464/// bevy_ptr::deconstruct_moving_ptr!({
1465///   let tuple { 0: field_a, 1: field_b, 2: field_c } = parent;
1466/// });
1467///
1468/// field_a.assign_to(&mut target_a);
1469/// field_b.assign_to(&mut target_b);
1470/// field_c.assign_to(&mut target_c);
1471///
1472/// assert_eq!(target_a.0, 11);
1473/// assert_eq!(target_b.0, 22);
1474/// assert_eq!(target_c.0, 33);
1475/// ```
1476///
1477/// ## `MaybeUninit`
1478///
1479/// ```
1480/// use core::mem::{offset_of, MaybeUninit};
1481/// use bevy_ptr::{MovingPtr, move_as_ptr};
1482/// # use bevy_ptr::Unaligned;
1483/// # struct FieldAType(usize);
1484/// # struct FieldBType(usize);
1485/// # struct FieldCType(usize);
1486///
1487/// # pub struct Parent {
1488/// #  pub field_a: FieldAType,
1489/// #  pub field_b: FieldBType,
1490/// #  pub field_c: FieldCType,
1491/// # }
1492///
1493/// let parent = MaybeUninit::new(Parent {
1494///   field_a: FieldAType(11),
1495///   field_b: FieldBType(22),
1496///   field_c: FieldCType(33),
1497/// });
1498///
1499/// let mut target_a = MaybeUninit::new(FieldAType(101));
1500/// let mut target_b = MaybeUninit::new(FieldBType(102));
1501/// let mut target_c = MaybeUninit::new(FieldCType(103));
1502///
1503/// // Converts `parent` into a `MovingPtr`
1504/// move_as_ptr!(parent);
1505///
1506/// // The field names must match the name used in the type definition.
1507/// // Each one will be a `MovingPtr` of the field's type.
1508/// bevy_ptr::deconstruct_moving_ptr!({
1509///   let MaybeUninit::<Parent> { field_a, field_b, field_c } = parent;
1510/// });
1511///
1512/// field_a.assign_to(&mut target_a);
1513/// field_b.assign_to(&mut target_b);
1514/// field_c.assign_to(&mut target_c);
1515///
1516/// unsafe {
1517///   assert_eq!(target_a.assume_init().0, 11);
1518///   assert_eq!(target_b.assume_init().0, 22);
1519///   assert_eq!(target_c.assume_init().0, 33);
1520/// }
1521/// ```
1522///
1523/// [`assign_to`]: MovingPtr::assign_to
1524#[macro_export]
1525macro_rules! deconstruct_moving_ptr {
1526    ({ let tuple { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => {
1527        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1528        let mut ptr: $crate::MovingPtr<_, _> = $ptr;
1529        let _ = || {
1530            let value = &mut *ptr;
1531            // Ensure that each field index exists and is mentioned only once
1532            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1533            ::core::hint::black_box(($(&mut value.$field_index,)*));
1534            // Ensure that `ptr` is a tuple and not something that derefs to it
1535            // Ensure that the number of patterns matches the number of fields
1536            fn unreachable<T>(_index: usize) -> T {
1537                ::core::unreachable!()
1538            }
1539            *value = ($(unreachable($field_index),)*);
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 $pattern = unsafe { ptr.move_field(|f| &raw mut (*f).$field_index) };)*
1547        #[expect(clippy::mem_forget, reason = "`deconstruct_moving_ptr` needs to forget the `MovingPtr` due to its safety requirements.")]
1548        ::core::mem::forget(ptr);
1549    };
1550    ({ let MaybeUninit::<tuple> { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => {
1551        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1552        let mut ptr: $crate::MovingPtr<::core::mem::MaybeUninit<_>, _> = $ptr;
1553        let _ = || {
1554            // SAFETY: This closure is never called
1555            let value = unsafe { ptr.assume_init_mut() };
1556            // Ensure that each field index exists and is mentioned only once
1557            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1558            ::core::hint::black_box(($(&mut value.$field_index,)*));
1559            // Ensure that `ptr` is a tuple and not something that derefs to it
1560            // Ensure that the number of patterns matches the number of fields
1561            fn unreachable<T>(_index: usize) -> T {
1562                ::core::unreachable!()
1563            }
1564            *value = ($(unreachable($field_index),)*);
1565        };
1566        // SAFETY:
1567        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1568        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1569        // - `mem::forget` is called on `self` immediately after these calls
1570        // - Each field is distinct, since otherwise the block of code above would fail compilation
1571        $(let $pattern = unsafe { ptr.move_maybe_uninit_field(|f| &raw mut (*f).$field_index) };)*
1572        #[expect(clippy::mem_forget, reason = "`deconstruct_moving_ptr` needs to forget the `MovingPtr` due to its safety requirements.")]
1573        ::core::mem::forget(ptr);
1574    };
1575    ({ let $struct_name:ident { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => {
1576        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1577        let mut ptr: $crate::MovingPtr<_, _> = $ptr;
1578        let _ = || {
1579            let value = &mut *ptr;
1580            // Ensure that each field index exists is mentioned only once
1581            // Ensure that each field is on the struct and not accessed using autoref
1582            let $struct_name { $($field_index: _),* } = value;
1583            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1584            ::core::hint::black_box(($(&mut value.$field_index),*));
1585            // Ensure that `ptr` is a `$struct_name` and not just something that derefs to it
1586            let value: *mut _ = value;
1587            // SAFETY: This closure is never called
1588            $struct_name { ..unsafe { value.read() } };
1589        };
1590        // SAFETY:
1591        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1592        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1593        // - `mem::forget` is called on `self` immediately after these calls
1594        // - Each field is distinct, since otherwise the block of code above would fail compilation
1595        $(let $crate::get_pattern!($field_index$(: $pattern)?) = unsafe { ptr.move_field(|f| &raw mut (*f).$field_index) };)*
1596        #[expect(clippy::mem_forget, reason = "`deconstruct_moving_ptr` needs to forget the `MovingPtr` due to its safety requirements.")]
1597        ::core::mem::forget(ptr);
1598    };
1599    ({ let MaybeUninit::<$struct_name:ident> { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => {
1600        // Specify the type to make sure the `mem::forget` doesn't forget a mere `&mut MovingPtr`
1601        let mut ptr: $crate::MovingPtr<::core::mem::MaybeUninit<_>, _> = $ptr;
1602        let _ = || {
1603            // SAFETY: This closure is never called
1604            let value = unsafe { ptr.assume_init_mut() };
1605            // Ensure that each field index exists is mentioned only once
1606            // Ensure that each field is on the struct and not accessed using autoref
1607            let $struct_name { $($field_index: _),* } = value;
1608            // Ensure that the struct is not `repr(packed)` and that we may take references to fields
1609            ::core::hint::black_box(($(&mut value.$field_index),*));
1610            // Ensure that `ptr` is a `$struct_name` and not just something that derefs to it
1611            let value: *mut _ = value;
1612            // SAFETY: This closure is never called
1613            $struct_name { ..unsafe { value.read() } };
1614        };
1615        // SAFETY:
1616        // - `f` does a raw pointer offset, which always returns a non-null pointer to a field inside `T`
1617        // - The struct is not `repr(packed)`, since otherwise the block of code above would fail compilation
1618        // - `mem::forget` is called on `self` immediately after these calls
1619        // - Each field is distinct, since otherwise the block of code above would fail compilation
1620        $(let $crate::get_pattern!($field_index$(: $pattern)?) = unsafe { ptr.move_maybe_uninit_field(|f| &raw mut (*f).$field_index) };)*
1621        #[expect(clippy::mem_forget, reason = "`deconstruct_moving_ptr` needs to forget the `MovingPtr` due to its safety requirements.")]
1622        ::core::mem::forget(ptr);
1623    };
1624}