about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-01-09 09:05:08 +0100
committerGitHub <noreply@github.com>2025-01-09 09:05:08 +0100
commit04e87154bb4133ab553f01506e672ded68c7dd6f (patch)
treedd5598b67a3d7fa078c6274fa77d18295705b4ce
parent84910fc3cd762a0cc2616167be844d4b99cc5b31 (diff)
parent2d236015410269fa6c9e9a8e921883832a9638e6 (diff)
downloadrust-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.rs48
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]