Skip to content

Commit 06a411b

Browse files
committed
Implement FromZeroes for thin raw pointers
Makes progress on #170
1 parent 1ede214 commit 06a411b

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/lib.rs

+32
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,35 @@ safety_comment! {
945945
unsafe_impl!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
946946
assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
947947
}
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+
}
948977
safety_comment! {
949978
/// SAFETY:
950979
/// Per the reference [1]:
@@ -3983,6 +4012,9 @@ mod tests {
39834012
assert_impls!(Unalign<u8>: FromZeroes, FromBytes, AsBytes, Unaligned);
39844013
assert_impls!(Unalign<NotZerocopy>: Unaligned, !FromZeroes, !FromBytes, !AsBytes);
39854014

4015+
assert_impls!(*const NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned);
4016+
assert_impls!(*mut NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned);
4017+
39864018
assert_impls!([u8]: FromZeroes, FromBytes, AsBytes, Unaligned);
39874019
assert_impls!([NotZerocopy]: !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
39884020
assert_impls!([u8; 0]: FromZeroes, FromBytes, AsBytes, Unaligned);

0 commit comments

Comments
 (0)