@@ -537,7 +537,10 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
537
537
#[ rustc_allow_const_fn_unstable( ptr_metadata) ]
538
538
#[ rustc_diagnostic_item = "ptr_null" ]
539
539
pub 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 ) }
541
544
}
542
545
543
546
/// Creates a null mutable raw pointer.
@@ -563,7 +566,10 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
563
566
#[ rustc_allow_const_fn_unstable( ptr_metadata) ]
564
567
#[ rustc_diagnostic_item = "ptr_null_mut" ]
565
568
pub 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 ) }
567
573
}
568
574
569
575
/// Creates an invalid pointer with the given address.
@@ -590,11 +596,10 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
590
596
#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
591
597
pub const fn invalid < T > ( addr : usize ) -> * const T {
592
598
// 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)
598
603
}
599
604
600
605
/// Creates an invalid mutable pointer with the given address.
@@ -621,11 +626,10 @@ pub const fn invalid<T>(addr: usize) -> *const T {
621
626
#[ unstable( feature = "strict_provenance" , issue = "95228" ) ]
622
627
pub const fn invalid_mut < T > ( addr : usize ) -> * mut T {
623
628
// 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)
629
633
}
630
634
631
635
/// Convert an address back to a pointer, picking up a previously 'exposed' provenance.
0 commit comments