Repository: rust-lang/rust
Pull request: stabilize ptr_as_ref_unchecked

FCP passed in rust-lang/rust#122034.

Closes rust-lang/rust#122034.

Changed files:
filename: compiler/rustc_resolve/src/lib.rs
patch: @@ -8,6 +8,7 @@
 
 // tidy-alphabetical-start
 #![allow(internal_features)]
+#![cfg_attr(bootstrap, feature(ptr_as_ref_unchecked))]
 #![feature(arbitrary_self_types)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
@@ -18,7 +19,6 @@
 #![feature(default_field_values)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
-#![feature(ptr_as_ref_unchecked)]
 #![feature(rustc_attrs)]
 #![feature(trim_prefix_suffix)]
 #![recursion_limit = "256"]

filename: library/core/src/ptr/const_ptr.rs
patch: @@ -239,7 +239,7 @@ impl<T: PointeeSized> *const T {
     /// let ptr: *const u8 = &10u8 as *const u8;
     ///
     /// unsafe {
-    ///     let val_back = &*ptr;
+    ///     let val_back = ptr.as_ref_unchecked();
     ///     assert_eq!(val_back, &10);
     /// }
     /// ```
@@ -259,6 +259,7 @@ impl<T: PointeeSized> *const T {
     ///
     /// [`is_null`]: #method.is_null
     /// [`as_uninit_ref`]: #method.as_uninit_ref
+    /// [`as_ref_unchecked`]: #method.as_ref_unchecked
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
     #[inline]
@@ -283,15 +284,14 @@ impl<T: PointeeSized> *const T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ptr_as_ref_unchecked)]
     /// let ptr: *const u8 = &10u8 as *const u8;
     ///
     /// unsafe {
     ///     assert_eq!(ptr.as_ref_unchecked(), &10);
     /// }
     /// ```
-    // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
-    #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+    #[stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {

filename: library/core/src/ptr/docs/as_ref.md
patch: @@ -1,6 +1,7 @@
 Returns `None` if the pointer is null, or else returns a shared reference to
 the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
-must be used instead.
+must be used instead. If the value is known to be non-null, [`as_ref_unchecked`]
+can be used instead.
 
 # Safety
 
@@ -14,6 +15,5 @@ determined to be null or not. See [`is_null`] for more information.
 
 # Null-unchecked version
 
-If you are sure the pointer can never be null and are looking for some kind of
-`as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
-dereference the pointer directly.
+If you are sure the pointer can never be null, you can use `as_ref_unchecked` which returns
+`&mut T` instead of `Option<&mut T>`.

filename: library/core/src/ptr/mut_ptr.rs
patch: @@ -230,7 +230,7 @@ impl<T: PointeeSized> *mut T {
     /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
     ///
     /// unsafe {
-    ///     let val_back = &*ptr;
+    ///     let val_back = ptr.as_ref_unchecked();
     ///     println!("We got back the value: {val_back}!");
     /// }
     /// ```
@@ -252,7 +252,8 @@ impl<T: PointeeSized> *mut T {
     /// For the mutable counterpart see [`as_mut`].
     ///
     /// [`is_null`]: #method.is_null-1
-    /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
+    /// [`as_uninit_ref`]: #method.as_uninit_ref-1
+    /// [`as_ref_unchecked`]: #method.as_ref_unchecked-1
     /// [`as_mut`]: #method.as_mut
 
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
@@ -281,15 +282,14 @@ impl<T: PointeeSized> *mut T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ptr_as_ref_unchecked)]
     /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
     ///
     /// unsafe {
     ///     println!("We got back the value: {}!", ptr.as_ref_unchecked());
     /// }
     /// ```
-    // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
-    #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+    #[stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
@@ -531,11 +531,13 @@ impl<T: PointeeSized> *mut T {
 
     /// Returns `None` if the pointer is null, or else returns a unique reference to
     /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_mut`]
-    /// must be used instead.
+    /// must be used instead. If the value is known to be non-null, [`as_mut_unchecked`]
+    /// can be used instead.
     ///
     /// For the shared counterpart see [`as_ref`].
     ///
     /// [`as_uninit_mut`]: #method.as_uninit_mut
+    /// [`as_mut_unchecked`]: #method.as_mut_unchecked
     /// [`as_ref`]: pointer#method.as_ref-1
     ///
     /// # Safety
@@ -564,14 +566,13 @@ impl<T: PointeeSized> *mut T {
     ///
     /// # Null-unchecked version
     ///
-    /// If you are sure the pointer can never be null and are looking for some kind of
-    /// `as_mut_unchecked` that returns the `&mut T` instead of `Option<&mut T>`, know that
-    /// you can dereference the pointer directly.
+    /// If you are sure the pointer can never be null, you can use `as_mut_unchecked` which returns
+    /// `&mut T` instead of `Option<&mut T>`.
     ///
     /// ```
     /// let mut s = [1, 2, 3];
     /// let ptr: *mut u32 = s.as_mut_ptr();
-    /// let first_value = unsafe { &mut *ptr };
+    /// let first_value = unsafe { ptr.as_mut_unchecked() };
     /// *first_value = 4;
     /// # assert_eq!(s, [4, 2, 3]);
     /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
@@ -603,16 +604,15 @@ impl<T: PointeeSized> *mut T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ptr_as_ref_unchecked)]
     /// let mut s = [1, 2, 3];
     /// let ptr: *mut u32 = s.as_mut_ptr();
     /// let first_value = unsafe { ptr.as_mut_unchecked() };
     /// *first_value = 4;
     /// # assert_eq!(s, [4, 2, 3]);
     /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
     /// ```
-    // FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized.
-    #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+    #[stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "ptr_as_ref_unchecked", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T {

filename: src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.rs
patch: @@ -1,6 +1,5 @@
 //@compile-flags: -Zmiri-deterministic-concurrency
 // A case that is not covered by `mixed_size_read_write`.
-#![feature(ptr_as_ref_unchecked)]
 
 use std::sync::atomic::*;
 use std::thread;