@@ -537,7 +537,10 @@ 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 of casting so that Miri knows that the pointer is invalid.
541+ // SAFETY: on all current platforms, usize and pointers have the same layout,
542+ // and the validity invariant of pointers is the same as that of integers
543+ unsafe { mem:: transmute ( 0usize ) }
541544}
542545
543546/// Creates a null mutable raw pointer.
@@ -563,7 +566,10 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
563566#[ rustc_allow_const_fn_unstable( ptr_metadata) ]
564567#[ rustc_diagnostic_item = "ptr_null_mut" ]
565568pub const fn null_mut < T : ?Sized + Thin > ( ) -> * mut T {
566- from_raw_parts_mut ( invalid_mut ( 0 ) , ( ) )
569+ // Use transmute instead of casting so that Miri knows that the pointer is invalid.
570+ // SAFETY: on all current platforms, usize and pointers have the same layout,
571+ // and the validity invariant of pointers is the same as that of integers
572+ unsafe { mem:: transmute ( 0usize ) }
567573}
568574
569575/// Creates an invalid pointer with the given address.
@@ -590,11 +596,10 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
590596#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
591597pub const fn invalid < T > ( addr : usize ) -> * const T {
592598 // 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) }
599+ // We offset the null pointer instead of using a cast so that LLVM doesn't
600+ // use inttoptr and so tools like Miri can tell that it is *not* the same
601+ // as from_exposed_addr.
602+ null :: < T > ( ) . wrapping_byte_add ( addr)
598603}
599604
600605/// Creates an invalid mutable pointer with the given address.
@@ -621,11 +626,10 @@ pub const fn invalid<T>(addr: usize) -> *const T {
621626#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
622627pub const fn invalid_mut < T > ( addr : usize ) -> * mut T {
623628 // 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) }
629+ // We offset the null pointer instead of using a cast so that LLVM doesn't
630+ // use inttoptr and so tools like Miri can tell that it is *not* the same
631+ // as from_exposed_addr.
632+ null_mut :: < T > ( ) . wrapping_byte_add ( addr)
629633}
630634
631635/// Convert an address back to a pointer, picking up a previously 'exposed' provenance.
0 commit comments