diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-09 09:05:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-09 09:05:08 +0100 |
| commit | 04e87154bb4133ab553f01506e672ded68c7dd6f (patch) | |
| tree | dd5598b67a3d7fa078c6274fa77d18295705b4ce | |
| parent | 84910fc3cd762a0cc2616167be844d4b99cc5b31 (diff) | |
| parent | 2d236015410269fa6c9e9a8e921883832a9638e6 (diff) | |
| download | rust-04e87154bb4133ab553f01506e672ded68c7dd6f.tar.gz rust-04e87154bb4133ab553f01506e672ded68c7dd6f.zip | |
Rollup merge of #135242 - RalfJung:nonnull-provenance, r=jhpratt
add missing provenance APIs on NonNull
This adds some provenance APIs that exist on raw pointers but have been forgotten on `NonNull`:
```rust
impl<T> NonNull<T> {
pub const fn without_provenance(addr: NonZero<usize>) -> Self;
pub fn from_exposed_provenance(addr: NonZero<usize>) -> Self;
}
impl<T: ?Sized> NonNull<T> {
pub fn expose_provenance(self) -> NonZero<usize>;
}
```
https://github.com/rust-lang/libs-team/issues/518 is the ACP for the two exposed provenance ones; I forgot to include `without_provenance` there but I hope that, too, is uncontroversial (and anyway this PR only adds things unstably). Cc `@rust-lang/libs-api`
Tracking issue: https://github.com/rust-lang/rust/issues/135243
| -rw-r--r-- | library/core/src/ptr/non_null.rs | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 1058fa42cc1..8e78a44bddc 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -85,6 +85,20 @@ impl<T: ?Sized> !Send for NonNull<T> {} impl<T: ?Sized> !Sync for NonNull<T> {} impl<T: Sized> NonNull<T> { + /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. + /// + /// For more details, see the equivalent method on a raw pointer, [`ptr::without_provenance_mut`]. + /// + /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub const fn without_provenance(addr: NonZero<usize>) -> Self { + // SAFETY: we know `addr` is non-zero. + unsafe { + let ptr = crate::ptr::without_provenance_mut(addr.get()); + NonNull::new_unchecked(ptr) + } + } + /// Creates a new `NonNull` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like @@ -116,6 +130,21 @@ impl<T: Sized> NonNull<T> { } } + /// Converts an address back to a mutable pointer, picking up some previously 'exposed' + /// [provenance][crate::ptr#provenance]. + /// + /// For more details, see the equivalent method on a raw pointer, [`ptr::with_exposed_provenance_mut`]. + /// + /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub fn with_exposed_provenance(addr: NonZero<usize>) -> Self { + // SAFETY: we know `addr` is non-zero. + unsafe { + let ptr = crate::ptr::with_exposed_provenance_mut(addr.get()); + NonNull::new_unchecked(ptr) + } + } + /// Returns a shared references to the value. In contrast to [`as_ref`], this does not require /// that the value has to be initialized. /// @@ -282,7 +311,7 @@ impl<T: ?Sized> NonNull<T> { /// Gets the "address" portion of the pointer. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] @@ -294,10 +323,23 @@ impl<T: ?Sized> NonNull<T> { unsafe { NonZero::new_unchecked(self.as_ptr().addr()) } } + /// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in + /// [`with_exposed_provenance`][NonNull::with_exposed_provenance] and returns the "address" portion. + /// + /// For more details, see the equivalent method on a raw pointer, [`pointer::expose_provenance`]. + /// + /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub fn expose_provenance(self) -> NonZero<usize> { + // SAFETY: The pointer is guaranteed by the type to be non-null, + // meaning that the address will be non-zero. + unsafe { NonZero::new_unchecked(self.as_ptr().expose_provenance()) } + } + /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of /// `self`. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::with_addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::with_addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] @@ -311,7 +353,7 @@ impl<T: ?Sized> NonNull<T> { /// Creates a new pointer by mapping `self`'s address to a new one, preserving the /// [provenance][crate::ptr#provenance] of `self`. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::map_addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::map_addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] |
