about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-24 17:14:26 +0000
committerbors <bors@rust-lang.org>2022-12-24 17:14:26 +0000
commit7e4f4660ebb4533de629b5d7d8ac10ed572d0f2e (patch)
tree569d4852433db40daf93edd422fb69e65536874b
parentf5c3dfdbbf06d5997079ac7339de5002f7ced2a3 (diff)
parent15f72dd29d083bfcade93ec2b57350c2b37feed6 (diff)
downloadrust-7e4f4660ebb4533de629b5d7d8ac10ed572d0f2e.tar.gz
rust-7e4f4660ebb4533de629b5d7d8ac10ed572d0f2e.zip
Auto merge of #104977 - RalfJung:ptr-from-ref, r=dtolnay
add ptr::from_{ref,mut}

We have methods to avoid almost all `as` casts around raw pointer handling, except for the initial cast from reference to raw pointer. These new methods close that gap.

(I also moved `null_mut` next to `null` to keep the file consistently organized.)

r? libs-api

Tracking issue: https://github.com/rust-lang/rust/issues/106116
-rw-r--r--library/core/src/ptr/mod.rs52
1 files changed, 37 insertions, 15 deletions
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 48b2e88da28..5f30029eaa0 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -516,6 +516,27 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
     from_raw_parts(invalid(0), ())
 }
 
+/// Creates a null mutable raw pointer.
+///
+/// # Examples
+///
+/// ```
+/// use std::ptr;
+///
+/// let p: *mut i32 = ptr::null_mut();
+/// assert!(p.is_null());
+/// ```
+#[inline(always)]
+#[must_use]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_promotable]
+#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
+#[rustc_allow_const_fn_unstable(ptr_metadata)]
+#[rustc_diagnostic_item = "ptr_null_mut"]
+pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
+    from_raw_parts_mut(invalid_mut(0), ())
+}
+
 /// Creates an invalid pointer with the given address.
 ///
 /// This is different from `addr as *const T`, which creates a pointer that picks up a previously
@@ -663,25 +684,26 @@ where
     addr as *mut T
 }
 
-/// Creates a null mutable raw pointer.
+/// Convert a reference to a raw pointer.
 ///
-/// # Examples
-///
-/// ```
-/// use std::ptr;
+/// This is equivalent to `r as *const T`, but is a bit safer since it will never silently change
+/// type or mutability, in particular if the code is refactored.
+#[inline(always)]
+#[must_use]
+#[unstable(feature = "ptr_from_ref", issue = "106116")]
+pub fn from_ref<T: ?Sized>(r: &T) -> *const T {
+    r
+}
+
+/// Convert a mutable reference to a raw pointer.
 ///
-/// let p: *mut i32 = ptr::null_mut();
-/// assert!(p.is_null());
-/// ```
+/// This is equivalent to `r as *mut T`, but is a bit safer since it will never silently change
+/// type or mutability, in particular if the code is refactored.
 #[inline(always)]
 #[must_use]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_promotable]
-#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
-#[rustc_allow_const_fn_unstable(ptr_metadata)]
-#[rustc_diagnostic_item = "ptr_null_mut"]
-pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
-    from_raw_parts_mut(invalid_mut(0), ())
+#[unstable(feature = "ptr_from_ref", issue = "106116")]
+pub fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
+    r
 }
 
 /// Forms a raw slice from a pointer and a length.