@@ -945,6 +945,40 @@ safety_comment! {
945
945
unsafe_impl!( T : ?Sized + Unaligned => Unaligned for ManuallyDrop <T >) ;
946
946
assert_unaligned!( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
947
947
}
948
+ safety_comment ! {
949
+ /// SAFETY:
950
+ /// The all-zeroes const and mut raw pointers are valid, and it is sound to
951
+ /// materialize them from nothing. The existence of `ptr::null` [1] and
952
+ /// `ptr::null_mut` [2], which are safe functions, guarantees this (if this
953
+ /// were not sound, these functions could not exist). Unlike non-null
954
+ /// pointers, it is always unsound to dereference null pointers, and so it's
955
+ /// not a footgun that converting from zeroes may not preserve pointer
956
+ /// provenance information.
957
+ ///
958
+ /// Since the encoding of fat pointers is not currently defined by the
959
+ /// reference, it would not be sound to implement `FromZeroes` for fat
960
+ /// pointer types such `*const T` for `T: ?Sized` or even for more
961
+ /// constrained pointer types such as `*const [T]` for `T: Sized`.
962
+ ///
963
+ /// Currently, though it would likely be sound, we choose not to implement
964
+ /// `FromBytes` or `AsBytes` for raw pointers because it would be easy for
965
+ /// code to mistakenly assume that converting from a raw pointer to a
966
+ /// different representation (such as a byte array) and back again via
967
+ /// `FromBytes` and `AsBytes` would result in a semantically identical
968
+ /// pointer. Thanks to provenance information, that may not actually be
969
+ /// true, so this would present a serious footgun. Note that this aspect of
970
+ /// Rust's memory model is still up in the air, so it's possible that these
971
+ /// conversions will one day be determined to be sound, at which point we
972
+ /// could choose to support these impls. See #170 for more information.
973
+ ///
974
+ /// [1] https://doc.rust-lang.org/core/ptr/fn.null.html
975
+ /// [2] https://doc.rust-lang.org/core/ptr/fn.null_mut.html
976
+ // TODO(https://github.com/rust-lang/reference/pull/1392#issuecomment-1696768191):
977
+ // Once the validity of materializing null pointers is guaranteed in the
978
+ // reference, cite that instead of `null` and `null_mut`.
979
+ unsafe_impl!( T : Sized => FromZeroes for * const T ) ;
980
+ unsafe_impl!( T : Sized => FromZeroes for * mut T ) ;
981
+ }
948
982
safety_comment ! {
949
983
/// SAFETY:
950
984
/// Per the reference [1]:
@@ -3983,6 +4017,9 @@ mod tests {
3983
4017
assert_impls ! ( Unalign <u8 >: FromZeroes , FromBytes , AsBytes , Unaligned ) ;
3984
4018
assert_impls ! ( Unalign <NotZerocopy >: Unaligned , !FromZeroes , !FromBytes , !AsBytes ) ;
3985
4019
4020
+ assert_impls ! ( * const NotZerocopy : FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
4021
+ assert_impls ! ( * mut NotZerocopy : FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
4022
+
3986
4023
assert_impls ! ( [ u8 ] : FromZeroes , FromBytes , AsBytes , Unaligned ) ;
3987
4024
assert_impls ! ( [ NotZerocopy ] : !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
3988
4025
assert_impls ! ( [ u8 ; 0 ] : FromZeroes , FromBytes , AsBytes , Unaligned ) ;
0 commit comments