@@ -537,7 +537,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
537537#[ rustc_allow_const_fn_unstable( ptr_metadata) ]
538538#[ rustc_diagnostic_item = "ptr_null" ]
539539pub const fn null < T : ?Sized + Thin > ( ) -> * const T {
540- from_raw_parts ( invalid ( 0 ) , ( ) )
540+ // Use transmute instead casting so that miri knows that the pointer is invalid.
541+ // SAFETY: every usize is a valid pointer (on all current platforms).
542+ unsafe { mem:: transmute ( 0usize ) }
541543}
542544
543545/// Creates a null mutable raw pointer.
@@ -563,7 +565,9 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
563565#[ rustc_allow_const_fn_unstable( ptr_metadata) ]
564566#[ rustc_diagnostic_item = "ptr_null_mut" ]
565567pub const fn null_mut < T : ?Sized + Thin > ( ) -> * mut T {
566- from_raw_parts_mut ( invalid_mut ( 0 ) , ( ) )
568+ // Use transmute instead casting so that miri knows that the pointer is invalid.
569+ // SAFETY: every usize is a valid pointer (on all current platforms).
570+ unsafe { mem:: transmute ( 0 ) }
567571}
568572
569573/// Creates an invalid pointer with the given address.
@@ -590,11 +594,10 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
590594#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
591595pub const fn invalid < T > ( addr : usize ) -> * const T {
592596 // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
593- // We use transmute rather than a cast so tools like Miri can tell that this
594- // is *not* the same as from_exposed_addr.
595- // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
596- // pointer).
597- unsafe { mem:: transmute ( addr) }
597+ // We offset the null pointer instead of using a cast so that LLVM doesn't
598+ // use inttoptr and so tools like Miri can tell that it is *not* the same
599+ // as from_exposed_addr.
600+ null :: < T > ( ) . wrapping_byte_add ( addr)
598601}
599602
600603/// Creates an invalid mutable pointer with the given address.
@@ -621,11 +624,10 @@ pub const fn invalid<T>(addr: usize) -> *const T {
621624#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
622625pub const fn invalid_mut < T > ( addr : usize ) -> * mut T {
623626 // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
624- // We use transmute rather than a cast so tools like Miri can tell that this
625- // is *not* the same as from_exposed_addr.
626- // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
627- // pointer).
628- unsafe { mem:: transmute ( addr) }
627+ // We offset the null pointer instead of using a cast so that LLVM doesn't
628+ // use inttoptr and so tools like Miri can tell that it is *not* the same
629+ // as from_exposed_addr.
630+ null_mut :: < T > ( ) . wrapping_byte_add ( addr)
629631}
630632
631633/// Convert an address back to a pointer, picking up a previously 'exposed' provenance.
0 commit comments