diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index ba8b0670147..0658ed812d1 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -507,10 +507,33 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 #[rustc_promotable]
 #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
 #[rustc_diagnostic_item = "ptr_null"]
+#[cfg(bootstrap)]
 pub const fn null<T>() -> *const T {
     invalid(0)
 }
 
+/// Creates a null raw pointer.
+///
+/// # Examples
+///
+/// ```
+/// use std::ptr;
+///
+/// let p: *const i32 = ptr::null();
+/// assert!(p.is_null());
+/// ```
+#[inline(always)]
+#[must_use]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_promotable]
+#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
+#[rustc_allow_const_fn_unstable(ptr_metadata)]
+#[rustc_diagnostic_item = "ptr_null"]
+#[cfg(not(bootstrap))]
+pub const fn null<T: ?Sized + Thin>() -> *const T {
+    from_raw_parts(0 as *const (), ())
+}
+
 /// Creates a null mutable raw pointer.
 ///
 /// # Examples
@@ -527,6 +550,7 @@ pub const fn null<T>() -> *const T {
 #[rustc_promotable]
 #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
 #[rustc_diagnostic_item = "ptr_null_mut"]
+#[cfg(bootstrap)]
 pub const fn null_mut<T>() -> *mut T {
     invalid_mut(0)
 }
@@ -657,6 +681,28 @@ where
     addr as *mut T
 }
 
+/// Creates a null mutable raw pointer.
+///
+/// # Examples
+///
+/// ```
+/// use std::ptr;
+///
+/// let p: *mut i32 = ptr::null_mut();
+/// assert!(p.is_null());
+/// ```
+#[inline(always)]
+#[must_use]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_promotable]
+#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
+#[rustc_allow_const_fn_unstable(ptr_metadata)]
+#[rustc_diagnostic_item = "ptr_null_mut"]
+#[cfg(not(bootstrap))]
+pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
+    from_raw_parts_mut(0 as *mut (), ())
+}
+
 /// Forms a raw slice from a pointer and a length.
 ///
 /// The `len` argument is the number of **elements**, not the number of bytes.
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index 03fe56022b0..c5242ad04de 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -93,6 +93,18 @@ fn test_is_null() {
 
     let nmi: *mut dyn ToString = null_mut::<isize>();
     assert!(nmi.is_null());
+
+    #[cfg(not(bootstrap))]
+    {
+        extern "C" {
+            type Extern;
+        }
+        let ec: *const Extern = null::<Extern>();
+        assert!(ec.is_null());
+
+        let em: *mut Extern = null_mut::<Extern>();
+        assert!(em.is_null());
+    }
 }
 
 #[test]
diff --git a/src/test/ui/cast/casts-issue-46365.rs b/src/test/ui/cast/casts-issue-46365.rs
index 3d0fea245c0..a2205b718c1 100644
--- a/src/test/ui/cast/casts-issue-46365.rs
+++ b/src/test/ui/cast/casts-issue-46365.rs
@@ -3,5 +3,5 @@ struct Lorem {
 }
 
 fn main() {
-    let _foo: *mut Lorem = core::ptr::null_mut(); // no error here
+    let _foo: *mut Lorem = core::ptr::NonNull::dangling().as_ptr(); // no error here
 }