From 3e07965244623ea709b842381f475178cf49879a Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 23 Sep 2022 17:52:31 +0200 Subject: [PATCH 1/2] const stabilize `NonNull::as_ref` --- library/core/src/ptr/non_null.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index b492d2f07bc13..ebed58ccf0389 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -367,13 +367,14 @@ impl NonNull { /// /// [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`] From 855b8b82a5859a5bd50a59757b2ddacf779784e0 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 23 Sep 2022 17:52:53 +0200 Subject: [PATCH 2/2] add tests for const `NonNull::as_ref` --- tests/ui/consts/const-eval/nonnull_as_ref.rs | 8 ++++++++ tests/ui/consts/const-eval/nonnull_as_ref_ub.rs | 6 ++++++ .../consts/const-eval/nonnull_as_ref_ub.stderr | 16 ++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref.rs create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref_ub.rs create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr 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 0000000000000..eb4683e2c3088 --- /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 = 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 0000000000000..3b48e972923d8 --- /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 = 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 0000000000000..de93cb0c3ca6a --- /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::::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`.