Skip to content

Commit

Permalink
Rollup merge of rust-lang#102198 - lukas-code:nonnull_as_ref, r=Amanieu
Browse files Browse the repository at this point in the history
`const`-stablilize `NonNull::as_ref`

A bunch of pointer to reference methods have been made unstably const some time ago in rust-lang#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: rust-lang#91822

``@rustbot`` label +T-libs-api -T-libs
  • Loading branch information
matthiaskrgr authored Jul 30, 2023
2 parents 27e3a74 + 855b8b8 commit e3ca397
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
5 changes: 3 additions & 2 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`]
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/consts/const-eval/nonnull_as_ref.rs
Original file line number Diff line number Diff line change
@@ -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() {}
6 changes: 6 additions & 0 deletions tests/ui/consts/const-eval/nonnull_as_ref_ub.rs
Original file line number Diff line number Diff line change
@@ -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() {}
16 changes: 16 additions & 0 deletions tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit e3ca397

Please sign in to comment.