Skip to content

Commit 19f1bdc

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

File tree

5 files changed

+49
-12
lines changed

5 files changed

+49
-12
lines changed

src/lib.rs

+37
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,40 @@ 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, 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+
}
948982
safety_comment! {
949983
/// SAFETY:
950984
/// Per the reference [1]:
@@ -3983,6 +4017,9 @@ mod tests {
39834017
assert_impls!(Unalign<u8>: FromZeroes, FromBytes, AsBytes, Unaligned);
39844018
assert_impls!(Unalign<NotZerocopy>: Unaligned, !FromZeroes, !FromBytes, !AsBytes);
39854019

4020+
assert_impls!(*const NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned);
4021+
assert_impls!(*mut NotZerocopy: FromZeroes, !FromBytes, !AsBytes, !Unaligned);
4022+
39864023
assert_impls!([u8]: FromZeroes, FromBytes, AsBytes, Unaligned);
39874024
assert_impls!([NotZerocopy]: !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
39884025
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

zerocopy-derive/tests/ui-stable/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-stable/derive_transparent.rs:23:19

zerocopy-derive/tests/ui-stable/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
= note: this error originates in the derive macro `FromZeroes` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -44,13 +44,13 @@ error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
4444
|
4545
= help: the following other types implement trait `FromZeroes`:
4646
()
47+
*const T
48+
*mut T
4749
AU16
4850
F32<O>
4951
F64<O>
5052
FromZeroes1
5153
I128<O>
52-
I16<O>
53-
I32<O>
5454
and $N others
5555
note: required by a bound in `FromBytes`
5656
--> $WORKSPACE/src/lib.rs

0 commit comments

Comments
 (0)