about summary refs log tree commit diff
path: root/library/core/src/ptr
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-17 11:18:57 +0000
committerbors <bors@rust-lang.org>2024-10-17 11:18:57 +0000
commite09bf4c07af8a424f9022bfe8d42ec714a51f0be (patch)
tree0aa83217a4da4a550ed80601e35381bb06db1c33 /library/core/src/ptr
parentecf6fc5336a7fe24607b8c394f34a4fcd20079c8 (diff)
parent6e4f8fea36cd04f623c46d99adc3c370b1879883 (diff)
downloadrust-e09bf4c07af8a424f9022bfe8d42ec714a51f0be.tar.gz
rust-e09bf4c07af8a424f9022bfe8d42ec714a51f0be.zip
Auto merge of #18317 - lnicola:sync-from-rust, r=Veykril
minor: sync from downstream
Diffstat (limited to 'library/core/src/ptr')
-rw-r--r--library/core/src/ptr/const_ptr.rs47
-rw-r--r--library/core/src/ptr/metadata.rs6
-rw-r--r--library/core/src/ptr/mod.rs38
-rw-r--r--library/core/src/ptr/mut_ptr.rs58
-rw-r--r--library/core/src/ptr/non_null.rs52
5 files changed, 128 insertions, 73 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index c9af7f13e46..72f4bc2c9da 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -63,21 +63,22 @@ impl<T: ?Sized> *const T {
         self as _
     }
 
-    /// Uses the pointer value in a new pointer of another type.
+    /// Uses the address value in a new pointer of another type.
     ///
-    /// In case `meta` is a (fat) pointer to an unsized type, this operation
-    /// will ignore the pointer part, whereas for (thin) pointers to sized
-    /// types, this has the same effect as a simple cast.
+    /// This operation will ignore the address part of its `meta` operand and discard existing
+    /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
+    /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
+    /// with new metadata such as slice lengths or `dyn`-vtable.
     ///
-    /// The resulting pointer will have provenance of `self`, i.e., for a fat
-    /// pointer, this operation is semantically the same as creating a new
-    /// fat pointer with the data pointer value of `self` but the metadata of
-    /// `meta`.
+    /// The resulting pointer will have provenance of `self`. This operation is semantically the
+    /// same as creating a new pointer with the data pointer value of `self` but the metadata of
+    /// `meta`, being fat or thin depending on the `meta` operand.
     ///
     /// # Examples
     ///
-    /// This function is primarily useful for allowing byte-wise pointer
-    /// arithmetic on potentially fat pointers:
+    /// This function is primarily useful for enabling pointer arithmetic on potentially fat
+    /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
+    /// recombined with its own original metadata.
     ///
     /// ```
     /// #![feature(set_ptr_value)]
@@ -91,8 +92,28 @@ impl<T: ?Sized> *const T {
     ///     println!("{:?}", &*ptr); // will print "3"
     /// }
     /// ```
+    ///
+    /// # *Incorrect* usage
+    ///
+    /// The provenance from pointers is *not* combined. The result must only be used to refer to the
+    /// address allowed by `self`.
+    ///
+    /// ```rust,no_run
+    /// #![feature(set_ptr_value)]
+    /// let x = 0u32;
+    /// let y = 1u32;
+    ///
+    /// let x = (&x) as *const u32;
+    /// let y = (&y) as *const u32;
+    ///
+    /// let offset = (x as usize - y as usize) / 4;
+    /// let bad = x.wrapping_add(offset).with_metadata_of(y);
+    ///
+    /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
+    /// println!("{:?}", unsafe { &*bad });
+    /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
-    #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
     pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
@@ -1278,7 +1299,7 @@ impl<T: ?Sized> *const T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1298,7 +1319,7 @@ impl<T: ?Sized> *const T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index feeaf78d3e7..09c4002dbc7 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -92,7 +92,7 @@ pub trait Thin = Pointee<Metadata = ()>;
 ///
 /// assert_eq!(std::ptr::metadata("foo"), 3_usize);
 /// ```
-#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")]
 #[inline]
 pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
     ptr_metadata(ptr)
@@ -106,7 +106,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
 ///
 /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
 #[unstable(feature = "ptr_metadata", issue = "81513")]
-#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")]
 #[inline]
 pub const fn from_raw_parts<T: ?Sized>(
     data_pointer: *const impl Thin,
@@ -120,7 +120,7 @@ pub const fn from_raw_parts<T: ?Sized>(
 ///
 /// See the documentation of [`from_raw_parts`] for more details.
 #[unstable(feature = "ptr_metadata", issue = "81513")]
-#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")]
 #[inline]
 pub const fn from_raw_parts_mut<T: ?Sized>(
     data_pointer: *mut impl Thin,
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 67f1b0cd16d..09ff7f8cab1 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -448,7 +448,7 @@
 
 use crate::cmp::Ordering;
 use crate::marker::FnPtr;
-use crate::mem::{self, MaybeUninit};
+use crate::mem::{self, MaybeUninit, SizedTypeProperties};
 use crate::{fmt, hash, intrinsics, ub_checks};
 
 mod alignment;
@@ -992,7 +992,7 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
 /// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
-#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")]
 #[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"]
 pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
     from_raw_parts_mut(data, len)
@@ -1165,10 +1165,12 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
             size: usize = size_of::<T>(),
             align: usize = align_of::<T>(),
             count: usize = count,
-        ) =>
-        ub_checks::is_aligned_and_not_null(x, align)
-            && ub_checks::is_aligned_and_not_null(y, align)
-            && ub_checks::is_nonoverlapping(x, y, size, count)
+        ) => {
+            let zero_size = size == 0 || count == 0;
+            ub_checks::is_aligned_and_not_null(x, align, zero_size)
+                && ub_checks::is_aligned_and_not_null(y, align, zero_size)
+                && ub_checks::is_nonoverlapping(x, y, size, count)
+        }
     );
 
     // Split up the slice into small power-of-two-sized chunks that LLVM is able
@@ -1263,7 +1265,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
+#[rustc_const_stable(feature = "const_replace", since = "1.83.0")]
 #[rustc_diagnostic_item = "ptr_replace"]
 pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
     // SAFETY: the caller must guarantee that `dst` is valid to be
@@ -1277,7 +1279,8 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
             (
                 addr: *const () = dst as *const (),
                 align: usize = align_of::<T>(),
-            ) => ub_checks::is_aligned_and_not_null(addr, align)
+                is_zst: bool = T::IS_ZST,
+            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
         );
         mem::replace(&mut *dst, src)
     }
@@ -1429,7 +1432,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
             (
                 addr: *const () = src as *const (),
                 align: usize = align_of::<T>(),
-            ) => ub_checks::is_aligned_and_not_null(addr, align)
+                is_zst: bool = T::IS_ZST,
+            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
         );
         crate::intrinsics::read_via_copy(src)
     }
@@ -1513,7 +1517,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
-#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_read_unaligned"]
 pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
@@ -1611,7 +1614,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
 #[rustc_diagnostic_item = "ptr_write"]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn write<T>(dst: *mut T, src: T) {
@@ -1634,7 +1637,8 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
             (
                 addr: *mut () = dst as *mut (),
                 align: usize = align_of::<T>(),
-            ) => ub_checks::is_aligned_and_not_null(addr, align)
+                is_zst: bool = T::IS_ZST,
+            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::write_via_move(dst, src)
     }
@@ -1719,7 +1723,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// ```
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
 #[rustc_diagnostic_item = "ptr_write_unaligned"]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
@@ -1806,7 +1810,8 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
             (
                 addr: *const () = src as *const (),
                 align: usize = align_of::<T>(),
-            ) => ub_checks::is_aligned_and_not_null(addr, align)
+                is_zst: bool = T::IS_ZST,
+            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::volatile_load(src)
     }
@@ -1885,7 +1890,8 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
             (
                 addr: *mut () = dst as *mut (),
                 align: usize = align_of::<T>(),
-            ) => ub_checks::is_aligned_and_not_null(addr, align)
+                is_zst: bool = T::IS_ZST,
+            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
         );
         intrinsics::volatile_store(dst, src);
     }
@@ -1909,7 +1915,7 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
 /// than trying to adapt this to accommodate that change.
 ///
 /// Any questions go to @nagisa.
-#[cfg_attr(not(bootstrap), allow(ptr_to_integer_transmute_in_consts))]
+#[allow(ptr_to_integer_transmute_in_consts)]
 #[lang = "align_offset"]
 pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
     // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index e458bb4642f..613d2c91ac6 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -45,21 +45,22 @@ impl<T: ?Sized> *mut T {
         self as _
     }
 
-    /// Uses the pointer value in a new pointer of another type.
+    /// Uses the address value in a new pointer of another type.
     ///
-    /// In case `meta` is a (fat) pointer to an unsized type, this operation
-    /// will ignore the pointer part, whereas for (thin) pointers to sized
-    /// types, this has the same effect as a simple cast.
+    /// This operation will ignore the address part of its `meta` operand and discard existing
+    /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
+    /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
+    /// with new metadata such as slice lengths or `dyn`-vtable.
     ///
-    /// The resulting pointer will have provenance of `self`, i.e., for a fat
-    /// pointer, this operation is semantically the same as creating a new
-    /// fat pointer with the data pointer value of `self` but the metadata of
-    /// `meta`.
+    /// The resulting pointer will have provenance of `self`. This operation is semantically the
+    /// same as creating a new pointer with the data pointer value of `self` but the metadata of
+    /// `meta`, being fat or thin depending on the `meta` operand.
     ///
     /// # Examples
     ///
-    /// This function is primarily useful for allowing byte-wise pointer
-    /// arithmetic on potentially fat pointers:
+    /// This function is primarily useful for enabling pointer arithmetic on potentially fat
+    /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
+    /// recombined with its own original metadata.
     ///
     /// ```
     /// #![feature(set_ptr_value)]
@@ -73,8 +74,27 @@ impl<T: ?Sized> *mut T {
     ///     println!("{:?}", &*ptr); // will print "3"
     /// }
     /// ```
+    ///
+    /// # *Incorrect* usage
+    ///
+    /// The provenance from pointers is *not* combined. The result must only be used to refer to the
+    /// address allowed by `self`.
+    ///
+    /// ```rust,no_run
+    /// #![feature(set_ptr_value)]
+    /// let mut x = 0u32;
+    /// let mut y = 1u32;
+    ///
+    /// let x = (&mut x) as *mut u32;
+    /// let y = (&mut y) as *mut u32;
+    ///
+    /// let offset = (x as usize - y as usize) / 4;
+    /// let bad = x.wrapping_add(offset).with_metadata_of(y);
+    ///
+    /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
+    /// println!("{:?}", unsafe { &*bad });
     #[unstable(feature = "set_ptr_value", issue = "75091")]
-    #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
     pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U
@@ -1358,7 +1378,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1378,7 +1398,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1398,7 +1418,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1418,7 +1438,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1449,7 +1469,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::write`]: crate::ptr::write()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn write(self, val: T)
@@ -1468,7 +1488,7 @@ impl<T: ?Sized> *mut T {
     /// [`ptr::write_bytes`]: crate::ptr::write_bytes()
     #[doc(alias = "memset")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn write_bytes(self, val: u8, count: usize)
@@ -1509,7 +1529,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn write_unaligned(self, val: T)
@@ -1658,7 +1678,6 @@ impl<T: ?Sized> *mut T {
     ///
     /// ```
     /// #![feature(const_pointer_is_aligned)]
-    /// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
     /// #[repr(align(4))]
@@ -1784,7 +1803,6 @@ impl<T: ?Sized> *mut T {
     /// ```
     /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
-    /// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 6c5834a1ece..3e4cae2b3ca 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -230,6 +230,24 @@ impl<T: ?Sized> NonNull<T> {
         }
     }
 
+    /// Converts a reference to a `NonNull` pointer.
+    #[unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[inline]
+    pub const fn from_ref(r: &T) -> Self {
+        // SAFETY: A reference cannot be null.
+        unsafe { NonNull { pointer: r as *const T } }
+    }
+
+    /// Converts a mutable reference to a `NonNull` pointer.
+    #[unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[inline]
+    pub const fn from_mut(r: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null.
+        unsafe { NonNull { pointer: r as *mut T } }
+    }
+
     /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
     /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer.
     ///
@@ -394,8 +412,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
-    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
-    #[rustc_const_stable(feature = "const_ptr_as_ref", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_as_ref", since = "1.83.0")]
     #[must_use]
     #[inline(always)]
     pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
@@ -923,7 +940,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     pub const unsafe fn copy_to(self, dest: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -943,7 +960,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -963,7 +980,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     pub const unsafe fn copy_from(self, src: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -983,7 +1000,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
     pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -1013,7 +1030,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     pub const unsafe fn write(self, val: T)
     where
         T: Sized,
@@ -1032,7 +1049,7 @@ impl<T: ?Sized> NonNull<T> {
     #[doc(alias = "memset")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     pub const unsafe fn write_bytes(self, val: u8, count: usize)
     where
         T: Sized,
@@ -1073,7 +1090,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+    #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")]
     pub const unsafe fn write_unaligned(self, val: T)
     where
         T: Sized,
@@ -1211,7 +1228,6 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// ```
     /// #![feature(const_nonnull_new)]
-    /// #![feature(const_option)]
     /// #![feature(const_pointer_is_aligned)]
     /// use std::ptr::NonNull;
     ///
@@ -1264,7 +1280,6 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// ```
     /// #![feature(const_pointer_is_aligned)]
-    /// #![feature(const_option)]
     /// #![feature(const_nonnull_new)]
     /// use std::ptr::NonNull;
     ///
@@ -1434,10 +1449,7 @@ impl<T> NonNull<[T]> {
     /// (Note that this example artificially demonstrates a use of this method,
     /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
     #[stable(feature = "nonnull_slice_from_raw_parts", since = "1.70.0")]
-    #[rustc_const_stable(
-        feature = "const_slice_from_raw_parts_mut",
-        since = "CURRENT_RUSTC_VERSION"
-    )]
+    #[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")]
     #[must_use]
     #[inline]
     pub const fn slice_from_raw_parts(data: NonNull<T>, len: usize) -> Self {
@@ -1755,9 +1767,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
     ///
     /// This conversion is safe and infallible since references cannot be null.
     #[inline]
-    fn from(reference: &mut T) -> Self {
-        // SAFETY: A mutable reference cannot be null.
-        unsafe { NonNull { pointer: reference as *mut T } }
+    fn from(r: &mut T) -> Self {
+        NonNull::from_mut(r)
     }
 }
 
@@ -1767,8 +1778,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
     ///
     /// This conversion is safe and infallible since references cannot be null.
     #[inline]
-    fn from(reference: &T) -> Self {
-        // SAFETY: A reference cannot be null.
-        unsafe { NonNull { pointer: reference as *const T } }
+    fn from(r: &T) -> Self {
+        NonNull::from_ref(r)
     }
 }