diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-07-30 20:36:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-30 20:36:34 +0200 |
| commit | e3ca397593795e0ffa95c5db2d4577dfdd1fb575 (patch) | |
| tree | 465d047fd2fbed840a13ea78099a5c6f14e42924 | |
| parent | 27e3a740ae28ed0d8ad27b617337cf4bfc6291d2 (diff) | |
| parent | 855b8b82a5859a5bd50a59757b2ddacf779784e0 (diff) | |
| download | rust-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.rs | 5 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/nonnull_as_ref.rs | 8 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/nonnull_as_ref_ub.rs | 6 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr | 16 |
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`. |
