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<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 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<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 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<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 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::<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`.