@@ -945,6 +945,35 @@ 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 (see e.g.
951
+ /// `ptr::null` [1] and `ptr::null_mut` [2]). Unlike non-null pointers, it
952
+ /// is always unsound to dereference null pointers, and so it's not a
953
+ /// footgun that converting from zeroes may not preserve pointer provenance
954
+ /// information.
955
+ ///
956
+ /// Since the encoding of fat pointers is not currently defined by the
957
+ /// reference, it would not be sound to implement `FromZeroes` for fat
958
+ /// pointer types such `*const T` for `T: ?Sized` or even for more
959
+ /// constrained pointer types such as `*const [T]` for `T: Sized`.
960
+ ///
961
+ /// Currently, though it would likely be sound, we choose not to implement
962
+ /// `FromBytes` or `AsBytes` for raw pointers because it would be easy for
963
+ /// code to mistakenly assume that converting from a raw pointer to a
964
+ /// different representation (such as a byte array) and back again via
965
+ /// `FromBytes` and `AsBytes` would result in a semantically identical
966
+ /// pointer. Thanks to provenance information, that may not actually be
967
+ /// true, so this would present a serious footgun. Note that this aspect of
968
+ /// Rust's memory model is still up in the air, so it's possible that these
969
+ /// conversions will one day be determined to be sound, at which point we
970
+ /// could choose to support these impls. See #170 for more information.
971
+ ///
972
+ /// [1] https://doc.rust-lang.org/core/ptr/fn.null.html
973
+ /// [2] https://doc.rust-lang.org/core/ptr/fn.null_mut.html
974
+ unsafe_impl!( T : Sized => FromZeroes for * const T ) ;
975
+ unsafe_impl!( T : Sized => FromZeroes for * mut T ) ;
976
+ }
948
977
safety_comment ! {
949
978
/// SAFETY:
950
979
/// Per the reference [1]:
@@ -3983,6 +4012,9 @@ mod tests {
3983
4012
assert_impls ! ( Unalign <u8 >: FromZeroes , FromBytes , AsBytes , Unaligned ) ;
3984
4013
assert_impls ! ( Unalign <NotZerocopy >: Unaligned , !FromZeroes , !FromBytes , !AsBytes ) ;
3985
4014
4015
+ assert_impls ! ( * const NotZerocopy : FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
4016
+ assert_impls ! ( * mut NotZerocopy : FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
4017
+
3986
4018
assert_impls ! ( [ u8 ] : FromZeroes , FromBytes , AsBytes , Unaligned ) ;
3987
4019
assert_impls ! ( [ NotZerocopy ] : !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
3988
4020
assert_impls ! ( [ u8 ; 0 ] : FromZeroes , FromBytes , AsBytes , Unaligned ) ;
0 commit comments