Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a614f5f

Browse files
committedAug 29, 2023
Implement FromZeroes for thin raw pointers
Makes progress on #170
1 parent 1ede214 commit a614f5f

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
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);

‎zerocopy-derive/tests/ui-nightly/derive_transparent.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
66
|
77
= help: the following other types implement trait `FromZeroes`:
88
()
9+
*const T
10+
*mut T
911
AU16
1012
F32<O>
1113
F64<O>
1214
I128<O>
1315
I16<O>
14-
I32<O>
15-
I64<O>
1616
and $N others
1717
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
1818
--> tests/ui-nightly/derive_transparent.rs:23:19

‎zerocopy-derive/tests/ui-nightly/late_compile_pass.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
66
|
77
= help: the following other types implement trait `FromZeroes`:
88
()
9+
*const T
10+
*mut T
911
AU16
1012
F32<O>
1113
F64<O>
1214
FromZeroes1
1315
I128<O>
14-
I16<O>
15-
I32<O>
1616
and $N others
1717
= help: see issue #48214
1818
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
@@ -46,13 +46,13 @@ error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
4646
|
4747
= help: the following other types implement trait `FromZeroes`:
4848
()
49+
*const T
50+
*mut T
4951
AU16
5052
F32<O>
5153
F64<O>
5254
FromZeroes1
5355
I128<O>
54-
I16<O>
55-
I32<O>
5656
and $N others
5757
note: required by a bound in `FromBytes`
5858
--> $WORKSPACE/src/lib.rs

0 commit comments

Comments
 (0)
Please sign in to comment.