about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-07-30 20:36:34 +0200
committerGitHub <noreply@github.com>2023-07-30 20:36:34 +0200
commite3ca397593795e0ffa95c5db2d4577dfdd1fb575 (patch)
tree465d047fd2fbed840a13ea78099a5c6f14e42924
parent27e3a740ae28ed0d8ad27b617337cf4bfc6291d2 (diff)
parent855b8b82a5859a5bd50a59757b2ddacf779784e0 (diff)
downloadrust-e3ca397593795e0ffa95c5db2d4577dfdd1fb575.tar.gz
rust-e3ca397593795e0ffa95c5db2d4577dfdd1fb575.zip
Rollup merge of #102198 - lukas-code:nonnull_as_ref, r=Amanieu
`const`-stablilize `NonNull::as_ref`

A bunch of pointer to reference methods have been made unstably const some time ago in #91823 under the feature gate `const_ptr_as_ref`.
Out of these, `NonNull::as_ref` can be implemented as a `const fn` in stable rust today, so i hereby propose to const stabilize this function only.

Tracking issue: #91822

``@rustbot`` label +T-libs-api -T-libs
-rw-r--r--library/core/src/ptr/non_null.rs5
-rw-r--r--tests/ui/consts/const-eval/nonnull_as_ref.rs8
-rw-r--r--tests/ui/consts/const-eval/nonnull_as_ref_ub.rs6
-rw-r--r--tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr16
4 files changed, 33 insertions, 2 deletions
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index a8074c8659b..9582ca9e0be 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -367,13 +367,14 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_stable(feature = "const_nonnull_as_ref", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline(always)]
     pub const unsafe fn as_ref<'a>(&self) -> &'a T {
         // SAFETY: the caller must guarantee that `self` meets all the
         // requirements for a reference.
-        unsafe { &*self.as_ptr() }
+        // `cast_const` avoids a mutable raw pointer deref.
+        unsafe { &*self.as_ptr().cast_const() }
     }
 
     /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`]
diff --git a/tests/ui/consts/const-eval/nonnull_as_ref.rs b/tests/ui/consts/const-eval/nonnull_as_ref.rs
new file mode 100644
index 00000000000..eb4683e2c30
--- /dev/null
+++ b/tests/ui/consts/const-eval/nonnull_as_ref.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+use std::ptr::NonNull;
+
+const NON_NULL: NonNull<u8> = unsafe { NonNull::new_unchecked((&42u8 as *const u8).cast_mut()) };
+const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() });
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs
new file mode 100644
index 00000000000..3b48e972923
--- /dev/null
+++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs
@@ -0,0 +1,6 @@
+use std::ptr::NonNull;
+
+const NON_NULL: NonNull<u8> = unsafe { NonNull::dangling() };
+const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() });
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
new file mode 100644
index 00000000000..de93cb0c3ca
--- /dev/null
+++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
@@ -0,0 +1,16 @@
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+   |
+   = note: dereferencing pointer failed: 0x1[noalloc] is a dangling pointer (it has no provenance)
+   |
+note: inside `NonNull::<u8>::as_ref::<'_>`
+  --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
+note: inside `_`
+  --> $DIR/nonnull_as_ref_ub.rs:4:39
+   |
+LL | const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() });
+   |                                       ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.