Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1
vendor/bevy_ptr/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"Cargo.lock":"dc486efb20bcb4a5a19a0f56ae9a925c856e9917adc907ed7498326da82f81fb","Cargo.toml":"168482ba07980add139c8b910999e41f35c4a7b78475cc104570ca269c90c182","LICENSE-APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE-MIT":"508a77d2e7b51d98adeed32648ad124b7b30241a8e70b2e72c99f92d8e5874d1","README.md":"18d626291fa46629380ca19f9b1ad2da8c0bb3cff7433b158db1b363e14af978","src/lib.rs":"37773c2f5e31984499069e401d090247c03c0c2eab63b9af86ab64a1541a832f"},"package":"df7370d0e46b60e071917711d0860721f5347bc958bf325975ae6913a5dfcf01"}

7
vendor/bevy_ptr/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bevy_ptr"
version = "0.16.1"

81
vendor/bevy_ptr/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,81 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2024"
rust-version = "1.85.0"
name = "bevy_ptr"
version = "0.16.1"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Utilities for working with untyped pointers in a more safe way"
homepage = "https://bevyengine.org"
readme = "README.md"
keywords = [
"bevy",
"no_std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/bevyengine/bevy"
resolver = "2"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"-Zunstable-options",
"--generate-link-to-definition",
]
[lib]
name = "bevy_ptr"
path = "src/lib.rs"
[dependencies]
[lints.clippy]
alloc_instead_of_core = "warn"
allow_attributes = "warn"
allow_attributes_without_reason = "warn"
doc_markdown = "warn"
manual_let_else = "warn"
match_same_arms = "warn"
needless_lifetimes = "allow"
nonstandard_macro_braces = "warn"
print_stderr = "warn"
print_stdout = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"
redundant_closure_for_method_calls = "warn"
redundant_else = "warn"
ref_as_ptr = "warn"
semicolon_if_nothing_returned = "warn"
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
too_long_first_doc_paragraph = "allow"
too_many_arguments = "allow"
type_complexity = "allow"
undocumented_unsafe_blocks = "warn"
unwrap_or_default = "warn"
[lints.rust]
missing_docs = "warn"
unsafe_code = "deny"
unsafe_op_in_unsafe_fn = "warn"
unused_qualifications = "warn"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(docsrs_dep)"]

176
vendor/bevy_ptr/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

19
vendor/bevy_ptr/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,19 @@
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

111
vendor/bevy_ptr/README.md vendored Normal file
View File

@@ -0,0 +1,111 @@
# Bevy Pointer
[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/bevyengine/bevy#license)
[![Crates.io](https://img.shields.io/crates/v/bevy_ptr.svg)](https://crates.io/crates/bevy_ptr)
[![Downloads](https://img.shields.io/crates/d/bevy_ptr.svg)](https://crates.io/crates/bevy_ptr)
[![Docs](https://docs.rs/bevy_ptr/badge.svg)](https://docs.rs/bevy_ptr/latest/bevy_ptr/)
[![Discord](https://img.shields.io/discord/691052431525675048.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bevy)
Pointers in computer programming are objects that store a memory address. They're a fundamental building block for constructing more
complex data structures.
They're also *the* definitive source of memory safety bugs: you can dereference a invalid (null) pointer, access a pointer after the underlying
memory has been freed, and even ignore type safety and misread or mutate the underlying memory improperly.
Rust is a programming language that heavily relies on its types to enforce correctness, and by proxy, memory safety. As a result,
Rust has an entire zoo of types for working with pointers, and a graph of safe and unsafe conversions that make working with them safer.
`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
to choose what invariants to uphold for their pointer, with the intent to enable building progressively safer abstractions.
## How to Build a Borrow (From Scratch)
Correctly and safety converting a pointer into a valid borrow is at the core of all `unsafe` code in Rust. Looking at the documentation for
[`(*const T)::as_ref`], a pointer must satisfy *all* of the following conditions:
* The pointer must be properly aligned.
* The pointer cannot be null, even for zero sized types.
* The pointer must be within bounds of a valid allocated object (on the stack or the heap).
* The pointer must point to an initialized instance of `T`.
* The newly assigned lifetime should be valid for the value that the pointer is targeting.
* 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
in time, and converting from `&T` to `&mut T` is never allowed.
Note 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
final set of constraints are going to be a superset of this list, not a subset.
This list already is non-trivial to satisfy in isolation. Thankfully, the Rust core/standard library provides a progressive list of pointer types that help
build these safety guarantees...
## Standard Pointers
|Pointer Type |Lifetime'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|
|-------------------|-----------|-------|--------------|-------|--------|----------------|------------------|
|`Box<T>` |Owned |Yes |Yes |Yes |Yes |Yes |Yes |
|`&'a mut T` |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|`&'a T` |Yes |No |Yes |Yes |Yes |No |Yes |
|`&'a UnsafeCell<T>`|Yes |Maybe |Yes |Yes |Yes |Yes |Yes |
|`NonNull<T>` |No |Yes |Yes |No |Yes |No |No |
|`*const T` |No |No |Yes |No |No |No |No |
|`*mut T` |No |Yes |Yes |No |No |No |No |
|`*const ()` |No |No |No |No |No |No |No |
|`*mut ()` |No |Yes |No |No |No |No |No |
`&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
without the use of `unsafe`.
`&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
base primitive for all interior mutability in the language: `Cell<T>`, `RefCell<T>`, `Mutex<T>`, `RwLock<T>`, etc. are all built on top of
`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.
`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
lifetimes and the alignment guarantees of borrows. Its only guarantees are that the pointer is not null and that it points to a valid instance
of type `T`. If you've ever worked with C++, `NonNull<T>` is very close to a C++ reference (`T&`).
`*const T` and `*mut T` are what most developers with a background in C or C++ would consider pointers.
`*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
untyped 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
cast 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
constraining 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
all 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.
[RawWaker]: https://doc.rust-lang.org/std/task/struct.RawWaker.html
## Available in Nightly
|Pointer Type |Lifetime'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|
|-------------------|-----------|-------|--------------|-------|--------|----------------|------------------|
|`Unique<T>` |Owned |Yes |Yes |Yes |Yes |Yes |Yes |
|`Shared<T>` |Owned* |Yes |Yes |Yes |Yes |No |Yes |
`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
as 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>`,
etc.
`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
multiple instances to collectively own the data it points to, and as a result, forbids getting a mutable borrow.
`bevy_ptr` does not support these types right now, but may support [polyfills] for these pointer types if the need arises.
[polyfills]: https://en.wikipedia.org/wiki/Polyfill_(programming)
## Available in `bevy_ptr`
|Pointer Type |Lifetime'ed|Mutable|Strongly Typed|Aligned|Not Null|Forbids Aliasing|Forbids Arithmetic|
|---------------------|-----------|-------|--------------|-------|--------|----------------|------------------|
|`ConstNonNull<T>` |No |No |Yes |No |Yes |No |Yes |
|`ThinSlicePtr<'a, T>`|Yes |No |Yes |Yes |Yes |Yes |Yes |
|`OwningPtr<'a>` |Yes |Yes |No |Maybe |Yes |Yes |No |
|`Ptr<'a>` |Yes |No |No |Maybe |Yes |No |No |
|`PtrMut<'a>` |Yes |Yes |No |Maybe |Yes |Yes |No |
`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
`NonNull<T>`'s `*mut T`.
`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
accessing elements in the slice is `unsafe`. In debug builds, the length is included and will be checked.
`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`.
They allow working with heterogenous type erased storage (i.e. ECS tables, typemaps) without the overhead of dynamic dispatch in a manner that progressively
translates back to safe borrows. These types also support optional alignment requirements at a type level, and will verify it on dereference in debug builds.

652
vendor/bevy_ptr/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,652 @@
#![doc = include_str!("../README.md")]
#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![expect(unsafe_code, reason = "Raw pointers are inherently unsafe.")]
#![doc(
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
)]
use core::{
cell::UnsafeCell,
fmt::{self, Debug, Formatter, Pointer},
marker::PhantomData,
mem::ManuallyDrop,
num::NonZeroUsize,
ptr::{self, NonNull},
};
/// Used as a type argument to [`Ptr`], [`PtrMut`] and [`OwningPtr`] to specify that the pointer is aligned.
#[derive(Debug, Copy, Clone)]
pub struct Aligned;
/// Used as a type argument to [`Ptr`], [`PtrMut`] and [`OwningPtr`] to specify that the pointer is not aligned.
#[derive(Debug, Copy, Clone)]
pub struct Unaligned;
/// Trait that is only implemented for [`Aligned`] and [`Unaligned`] to work around the lack of ability
/// to have const generics of an enum.
pub trait IsAligned: sealed::Sealed {}
impl IsAligned for Aligned {}
impl IsAligned for Unaligned {}
mod sealed {
pub trait Sealed {}
impl Sealed for super::Aligned {}
impl Sealed for super::Unaligned {}
}
/// A newtype around [`NonNull`] that only allows conversion to read-only borrows or pointers.
///
/// This type can be thought of as the `*const T` to [`NonNull<T>`]'s `*mut T`.
#[repr(transparent)]
pub struct ConstNonNull<T: ?Sized>(NonNull<T>);
impl<T: ?Sized> ConstNonNull<T> {
/// Creates a new `ConstNonNull` if `ptr` is non-null.
///
/// # Examples
///
/// ```
/// use bevy_ptr::ConstNonNull;
///
/// let x = 0u32;
/// let ptr = ConstNonNull::<u32>::new(&x as *const _).expect("ptr is null!");
///
/// if let Some(ptr) = ConstNonNull::<u32>::new(core::ptr::null()) {
/// unreachable!();
/// }
/// ```
pub fn new(ptr: *const T) -> Option<Self> {
NonNull::new(ptr.cast_mut()).map(Self)
}
/// Creates a new `ConstNonNull`.
///
/// # Safety
///
/// `ptr` must be non-null.
///
/// # Examples
///
/// ```
/// use bevy_ptr::ConstNonNull;
///
/// let x = 0u32;
/// let ptr = unsafe { ConstNonNull::new_unchecked(&x as *const _) };
/// ```
///
/// *Incorrect* usage of this function:
///
/// ```rust,no_run
/// use bevy_ptr::ConstNonNull;
///
/// // NEVER DO THAT!!! This is undefined behavior. ⚠️
/// let ptr = unsafe { ConstNonNull::<u32>::new_unchecked(core::ptr::null()) };
/// ```
pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
// SAFETY: This function's safety invariants are identical to `NonNull::new_unchecked`
// The caller must satisfy all of them.
unsafe { Self(NonNull::new_unchecked(ptr.cast_mut())) }
}
/// Returns a shared reference to the value.
///
/// # Safety
///
/// When calling this method, you have to ensure that all of the following is true:
///
/// * The pointer must be properly aligned.
///
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
///
/// * The pointer must point to an initialized instance of `T`.
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
/// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
/// (The part about being initialized is not yet fully decided, but until
/// it is, the only safe approach is to ensure that they are indeed initialized.)
///
/// # Examples
///
/// ```
/// use bevy_ptr::ConstNonNull;
///
/// let mut x = 0u32;
/// let ptr = ConstNonNull::new(&mut x as *mut _).expect("ptr is null!");
///
/// let ref_x = unsafe { ptr.as_ref() };
/// println!("{ref_x}");
/// ```
///
/// [the module documentation]: core::ptr#safety
#[inline]
pub unsafe fn as_ref<'a>(&self) -> &'a T {
// SAFETY: This function's safety invariants are identical to `NonNull::as_ref`
// The caller must satisfy all of them.
unsafe { self.0.as_ref() }
}
}
impl<T: ?Sized> From<NonNull<T>> for ConstNonNull<T> {
fn from(value: NonNull<T>) -> ConstNonNull<T> {
ConstNonNull(value)
}
}
impl<'a, T: ?Sized> From<&'a T> for ConstNonNull<T> {
fn from(value: &'a T) -> ConstNonNull<T> {
ConstNonNull(NonNull::from(value))
}
}
impl<'a, T: ?Sized> From<&'a mut T> for ConstNonNull<T> {
fn from(value: &'a mut T) -> ConstNonNull<T> {
ConstNonNull(NonNull::from(value))
}
}
/// Type-erased borrow of some unknown type chosen when constructing this type.
///
/// This type tries to act "borrow-like" which means that:
/// - It should be considered immutable: its target must not be changed while this pointer is alive.
/// - It must always points to a valid value of whatever the pointee type is.
/// - The lifetime `'a` accurately represents how long the pointer is valid for.
/// - Must be sufficiently aligned for the unknown pointee type.
///
/// It may be helpful to think of this type as similar to `&'a dyn Any` but without
/// the metadata and able to point to data that does not correspond to a Rust type.
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct Ptr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a u8, A)>);
/// Type-erased mutable borrow of some unknown type chosen when constructing this type.
///
/// This type tries to act "borrow-like" which means that:
/// - Pointer is considered exclusive and mutable. It cannot be cloned as this would lead to
/// aliased mutability.
/// - It must always points to a valid value of whatever the pointee type is.
/// - The lifetime `'a` accurately represents how long the pointer is valid for.
/// - Must be sufficiently aligned for the unknown pointee type.
///
/// It may be helpful to think of this type as similar to `&'a mut dyn Any` but without
/// the metadata and able to point to data that does not correspond to a Rust type.
#[repr(transparent)]
pub struct PtrMut<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
/// Type-erased Box-like pointer to some unknown type chosen when constructing this type.
///
/// Conceptually represents ownership of whatever data is being pointed to and so is
/// responsible for calling its `Drop` impl. This pointer is _not_ responsible for freeing
/// the memory pointed to by this pointer as it may be pointing to an element in a `Vec` or
/// to a local in a function etc.
///
/// This type tries to act "borrow-like" like which means that:
/// - Pointer should be considered exclusive and mutable. It cannot be cloned as this would lead
/// to aliased mutability and potentially use after free bugs.
/// - It must always points to a valid value of whatever the pointee type is.
/// - The lifetime `'a` accurately represents how long the pointer is valid for.
/// - Must be sufficiently aligned for the unknown pointee type.
///
/// It may be helpful to think of this type as similar to `&'a mut ManuallyDrop<dyn Any>` but
/// without the metadata and able to point to data that does not correspond to a Rust type.
#[repr(transparent)]
pub struct OwningPtr<'a, A: IsAligned = Aligned>(NonNull<u8>, PhantomData<(&'a mut u8, A)>);
macro_rules! impl_ptr {
($ptr:ident) => {
impl<'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(
// SAFETY: The caller upholds safety for `offset` and ensures the result is not null.
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(
// SAFETY: The caller upholds safety for `add` and ensures the result is not null.
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 {
write!(f, "{}<Aligned>({:?})", stringify!($ptr), self.0)
}
}
impl Debug for $ptr<'_, Unaligned> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}<Unaligned>({:?})", stringify!($ptr), self.0)
}
}
};
}
impl_ptr!(Ptr);
impl_ptr!(PtrMut);
impl_ptr!(OwningPtr);
impl<'a, A: IsAligned> Ptr<'a, A> {
/// Creates a new instance from a raw pointer.
///
/// # Safety
/// - `inner` must point to valid value of whatever the pointee type is.
/// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
/// - `inner` must have correct provenance to allow reads of the pointee type.
/// - The lifetime `'a` must be constrained such that this [`Ptr`] will stay valid and nothing
/// can mutate the pointee while this [`Ptr`] is live except through an [`UnsafeCell`].
#[inline]
pub unsafe fn new(inner: NonNull<u8>) -> Self {
Self(inner, PhantomData)
}
/// Transforms this [`Ptr`] into an [`PtrMut`]
///
/// # Safety
/// * The data pointed to by this `Ptr` must be valid for writes.
/// * There must be no active references (mutable or otherwise) to the data underlying this `Ptr`.
/// * Another [`PtrMut`] for the same [`Ptr`] must not be created until the first is dropped.
#[inline]
pub unsafe fn assert_unique(self) -> PtrMut<'a, A> {
PtrMut(self.0, PhantomData)
}
/// Transforms this [`Ptr<T>`] into a `&T` with the same lifetime
///
/// # Safety
/// - `T` must be the erased pointee type for this [`Ptr`].
/// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
/// for the pointee type `T`.
#[inline]
pub unsafe fn deref<T>(self) -> &'a T {
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
unsafe { &*ptr }
}
/// Gets the underlying pointer, erasing the associated lifetime.
///
/// If possible, it is strongly encouraged to use [`deref`](Self::deref) over this function,
/// as it retains the lifetime.
#[inline]
pub fn as_ptr(self) -> *mut u8 {
self.0.as_ptr()
}
}
impl<'a, T: ?Sized> From<&'a T> for Ptr<'a> {
#[inline]
fn from(val: &'a T) -> Self {
// SAFETY: The returned pointer has the same lifetime as the passed reference.
// Access is immutable.
unsafe { Self::new(NonNull::from(val).cast()) }
}
}
impl<'a, A: IsAligned> PtrMut<'a, A> {
/// Creates a new instance from a raw pointer.
///
/// # Safety
/// - `inner` must point to valid value of whatever the pointee type is.
/// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
/// - `inner` must have correct provenance to allow read and writes of the pointee type.
/// - The lifetime `'a` must be constrained such that this [`PtrMut`] will stay valid and nothing
/// else can read or mutate the pointee while this [`PtrMut`] is live.
#[inline]
pub unsafe fn new(inner: NonNull<u8>) -> Self {
Self(inner, PhantomData)
}
/// Transforms this [`PtrMut`] into an [`OwningPtr`]
///
/// # Safety
/// Must have right to drop or move out of [`PtrMut`].
#[inline]
pub unsafe fn promote(self) -> OwningPtr<'a, A> {
OwningPtr(self.0, PhantomData)
}
/// Transforms this [`PtrMut<T>`] into a `&mut T` with the same lifetime
///
/// # Safety
/// - `T` must be the erased pointee type for this [`PtrMut`].
/// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
/// for the pointee type `T`.
#[inline]
pub unsafe fn deref_mut<T>(self) -> &'a mut T {
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensures the pointee is of type `T` and the pointer can be dereferenced.
unsafe { &mut *ptr }
}
/// Gets the underlying pointer, erasing the associated lifetime.
///
/// If possible, it is strongly encouraged to use [`deref_mut`](Self::deref_mut) over
/// this function, as it retains the lifetime.
#[inline]
pub fn as_ptr(&self) -> *mut u8 {
self.0.as_ptr()
}
/// Gets a [`PtrMut`] from this with a smaller lifetime.
#[inline]
pub fn reborrow(&mut self) -> PtrMut<'_, A> {
// SAFETY: the ptrmut we're borrowing from is assumed to be valid
unsafe { PtrMut::new(self.0) }
}
/// Gets an immutable reference from this mutable reference
#[inline]
pub fn as_ref(&self) -> Ptr<'_, A> {
// SAFETY: The `PtrMut` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
unsafe { Ptr::new(self.0) }
}
}
impl<'a, T: ?Sized> From<&'a mut T> for PtrMut<'a> {
#[inline]
fn from(val: &'a mut T) -> Self {
// SAFETY: The returned pointer has the same lifetime as the passed reference.
// The reference is mutable, and thus will not alias.
unsafe { Self::new(NonNull::from(val).cast()) }
}
}
impl<'a> OwningPtr<'a> {
/// This exists mostly to reduce compile times;
/// code is only duplicated per type, rather than per function called.
///
/// # Safety
///
/// Safety constraints of [`PtrMut::promote`] must be upheld.
unsafe fn make_internal<T>(temp: &mut ManuallyDrop<T>) -> OwningPtr<'_> {
// SAFETY: The constraints of `promote` are upheld by caller.
unsafe { PtrMut::from(&mut *temp).promote() }
}
/// Consumes a value and creates an [`OwningPtr`] to it while ensuring a double drop does not happen.
#[inline]
pub fn make<T, F: FnOnce(OwningPtr<'_>) -> R, R>(val: T, f: F) -> R {
let mut val = ManuallyDrop::new(val);
// SAFETY: The value behind the pointer will not get dropped or observed later,
// so it's safe to promote it to an owning pointer.
f(unsafe { Self::make_internal(&mut val) })
}
}
impl<'a, A: IsAligned> OwningPtr<'a, A> {
/// Creates a new instance from a raw pointer.
///
/// # Safety
/// - `inner` must point to valid value of whatever the pointee type is.
/// - If the `A` type parameter is [`Aligned`] then `inner` must be sufficiently aligned for the pointee type.
/// - `inner` must have correct provenance to allow read and writes of the pointee type.
/// - The lifetime `'a` must be constrained such that this [`OwningPtr`] will stay valid and nothing
/// else can read or mutate the pointee while this [`OwningPtr`] is live.
#[inline]
pub unsafe fn new(inner: NonNull<u8>) -> Self {
Self(inner, PhantomData)
}
/// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
///
/// # Safety
/// - `T` must be the erased pointee type for this [`OwningPtr`].
/// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
/// for the pointee type `T`.
#[inline]
pub unsafe fn read<T>(self) -> T {
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read`.
unsafe { ptr.read() }
}
/// Consumes the [`OwningPtr`] to drop the underlying data of type `T`.
///
/// # Safety
/// - `T` must be the erased pointee type for this [`OwningPtr`].
/// - If the type parameter `A` is [`Unaligned`] then this pointer must be sufficiently aligned
/// for the pointee type `T`.
#[inline]
pub unsafe fn drop_as<T>(self) {
let ptr = self.as_ptr().cast::<T>().debug_ensure_aligned();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `drop_in_place`.
unsafe {
ptr.drop_in_place();
}
}
/// Gets the underlying pointer, erasing the associated lifetime.
///
/// If possible, it is strongly encouraged to use the other more type-safe functions
/// over this function.
#[inline]
pub fn as_ptr(&self) -> *mut u8 {
self.0.as_ptr()
}
/// Gets an immutable pointer from this owned pointer.
#[inline]
pub fn as_ref(&self) -> Ptr<'_, A> {
// SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
unsafe { Ptr::new(self.0) }
}
/// Gets a mutable pointer from this owned pointer.
#[inline]
pub fn as_mut(&mut self) -> PtrMut<'_, A> {
// SAFETY: The `Owning` type's guarantees about the validity of this pointer are a superset of `Ptr` s guarantees
unsafe { PtrMut::new(self.0) }
}
}
impl<'a> OwningPtr<'a, Unaligned> {
/// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`.
///
/// # Safety
/// - `T` must be the erased pointee type for this [`OwningPtr`].
pub unsafe fn read_unaligned<T>(self) -> T {
let ptr = self.as_ptr().cast::<T>();
// SAFETY: The caller ensure the pointee is of type `T` and uphold safety for `read_unaligned`.
unsafe { ptr.read_unaligned() }
}
}
/// Conceptually equivalent to `&'a [T]` but with length information cut out for performance reasons
pub struct ThinSlicePtr<'a, T> {
ptr: NonNull<T>,
#[cfg(debug_assertions)]
len: usize,
_marker: PhantomData<&'a [T]>,
}
impl<'a, T> ThinSlicePtr<'a, T> {
#[inline]
/// Indexes the slice without doing bounds checks
///
/// # Safety
/// `index` must be in-bounds.
pub unsafe fn get(self, index: usize) -> &'a T {
#[cfg(debug_assertions)]
debug_assert!(index < self.len);
let ptr = self.ptr.as_ptr();
// SAFETY: `index` is in-bounds so the resulting pointer is valid to dereference.
unsafe { &*ptr.add(index) }
}
}
impl<'a, T> Clone for ThinSlicePtr<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Copy for ThinSlicePtr<'a, T> {}
impl<'a, T> From<&'a [T]> for ThinSlicePtr<'a, T> {
#[inline]
fn from(slice: &'a [T]) -> Self {
let ptr = slice.as_ptr().cast_mut();
Self {
// SAFETY: a reference can never be null
ptr: unsafe { NonNull::new_unchecked(ptr.debug_ensure_aligned()) },
#[cfg(debug_assertions)]
len: slice.len(),
_marker: PhantomData,
}
}
}
/// Creates a dangling pointer with specified alignment.
/// See [`NonNull::dangling`].
pub const fn dangling_with_align(align: NonZeroUsize) -> NonNull<u8> {
debug_assert!(align.is_power_of_two(), "Alignment must be power of two.");
// SAFETY: The pointer will not be null, since it was created
// from the address of a `NonZero<usize>`.
// TODO: use https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.with_addr once stabilized
unsafe { NonNull::new_unchecked(ptr::null_mut::<u8>().wrapping_add(align.get())) }
}
mod private {
use core::cell::UnsafeCell;
pub trait SealedUnsafeCell {}
impl<'a, T> SealedUnsafeCell for &'a UnsafeCell<T> {}
}
/// Extension trait for helper methods on [`UnsafeCell`]
pub trait UnsafeCellDeref<'a, T>: private::SealedUnsafeCell {
/// # Safety
/// - The returned value must be unique and not alias any mutable or immutable references to the contents of the [`UnsafeCell`].
/// - 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).
unsafe fn deref_mut(self) -> &'a mut T;
/// # Safety
/// - For the lifetime `'a` of the returned value you must not construct a mutable reference to the contents of the [`UnsafeCell`].
/// - 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).
unsafe fn deref(self) -> &'a T;
/// Returns a copy of the contained value.
///
/// # Safety
/// - The [`UnsafeCell`] must not currently have a mutable reference to its content.
/// - 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).
unsafe fn read(self) -> T
where
T: Copy;
}
impl<'a, T> UnsafeCellDeref<'a, T> for &'a UnsafeCell<T> {
#[inline]
unsafe fn deref_mut(self) -> &'a mut T {
// SAFETY: The caller upholds the alias rules.
unsafe { &mut *self.get() }
}
#[inline]
unsafe fn deref(self) -> &'a T {
// SAFETY: The caller upholds the alias rules.
unsafe { &*self.get() }
}
#[inline]
unsafe fn read(self) -> T
where
T: Copy,
{
// SAFETY: The caller upholds the alias rules.
unsafe { self.get().read() }
}
}
trait DebugEnsureAligned {
fn debug_ensure_aligned(self) -> Self;
}
// Disable this for miri runs as it already checks if pointer to reference
// casts are properly aligned.
#[cfg(all(debug_assertions, not(miri)))]
impl<T: Sized> DebugEnsureAligned for *mut T {
#[track_caller]
fn debug_ensure_aligned(self) -> Self {
let align = align_of::<T>();
// Implementation shamelessly borrowed from the currently unstable
// ptr.is_aligned_to.
//
// Replace once https://github.com/rust-lang/rust/issues/96284 is stable.
assert_eq!(
self as usize & (align - 1),
0,
"pointer is not aligned. Address {:p} does not have alignment {} for type {}",
self,
align,
core::any::type_name::<T>()
);
self
}
}
#[cfg(any(not(debug_assertions), miri))]
impl<T: Sized> DebugEnsureAligned for *mut T {
#[inline(always)]
fn debug_ensure_aligned(self) -> Self {
self
}
}