Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TODOs related to #429 and quotes to safety comments. #433

Merged
merged 5 commits into from
Nov 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 54 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,9 @@ safety_comment! {
/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
/// validity as `T`
///
/// TODO(#429): Once this text (added in
/// TODO(#429):
/// - Add quotes from docs.
/// - Once [1] (added in
/// https://github.com/rust-lang/rust/pull/115522) is available on stable,
/// quote the stable docs instead of the nightly docs.
unsafe_impl_known_layout!(#[repr([u8])] str);
Expand Down Expand Up @@ -965,6 +967,8 @@ pub unsafe trait FromZeroes {
// as required by `u8`.
// - Since `Self: FromZeroes`, the all-zeroes instance is a valid
// instance of `Self.`
//
// TODO(#429): Add references to docs and quotes.
joshlf marked this conversation as resolved.
Show resolved Hide resolved
unsafe { ptr::write_bytes(slf.cast::<u8>(), 0, len) };
}

Expand Down Expand Up @@ -1605,6 +1609,8 @@ pub unsafe trait AsBytes {
// - The total size of the resulting slice is no larger than
// `isize::MAX` because no allocation produced by safe code can be
// larger than `isize::MAX`.
//
// TODO(#429): Add references to docs and quotes.
joshlf marked this conversation as resolved.
Show resolved Hide resolved
unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
}

Expand Down Expand Up @@ -1640,6 +1646,8 @@ pub unsafe trait AsBytes {
// - The total size of the resulting slice is no larger than
// `isize::MAX` because no allocation produced by safe code can be
// larger than `isize::MAX`.
//
// TODO(#429): Add references to docs and quotes.
joshlf marked this conversation as resolved.
Show resolved Hide resolved
unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
}

Expand Down Expand Up @@ -1736,6 +1744,8 @@ safety_comment! {
/// - The only value >= 1 for which 1 is an integer multiple is 1
/// Therefore, the only possible alignment for `u8` and `i8` is 1.
///
/// TODO(#429): Add quotes from documentation.
///
/// [1] TODO(https://github.com/rust-lang/reference/issues/1291): Once the
/// reference explicitly guarantees these properties, cite it.
/// [2] https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout
Expand All @@ -1762,7 +1772,9 @@ safety_comment! {
/// - `AsBytes`: the `{f32,f64}::to_bits` methods' documentation [4,5]
/// states that they are currently equivalent to `transmute`. [3]
///
/// TODO: Make these arguments more precisely in terms of the documentation.
/// TODO(#429):
/// - Make these arguments more precisely in terms of the documentation.
/// - Add quotes from documentation.
///
/// [1] https://doc.rust-lang.org/nightly/std/primitive.f32.html#method.from_bits
/// [2] https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.from_bits
Expand All @@ -1776,11 +1788,12 @@ safety_comment! {

safety_comment! {
/// SAFETY:
/// - `FromZeroes`: Per the reference [1], 0x00 is a valid bit pattern for
/// `bool`.
/// - `AsBytes`: Per the reference [1], `bool` always has a size of 1 with
/// valid bit patterns 0x01 and 0x00, so the only byte of the bool is
/// always initialized
/// - `FromZeroes`: Valid since "[t]he value false has the bit pattern
/// 0x00" [1].
/// - `AsBytes`: Since "the boolean type has a size and alignment of 1 each"
/// and "The value false has the bit pattern 0x00 and the value true has
joshlf marked this conversation as resolved.
Show resolved Hide resolved
/// the bit pattern 0x01" [1]. Thus, the only byte of the bool is always
/// initialized.
/// - `Unaligned`: Per the reference [1], "[a]n object with the boolean type
/// has a size and alignment of 1 each."
///
Expand All @@ -1790,24 +1803,28 @@ safety_comment! {
}
safety_comment! {
/// SAFETY:
/// - `FromZeroes`: Per the reference [1], 0x0000 is a valid bit pattern for
/// `char`.
/// - `AsBytes`: `char` is represented as a 32-bit unsigned word (`u32`)
/// [1], which is `AsBytes`. Note that unlike `u32`, not all bit patterns
/// are valid for `char`.
/// - `FromZeroes`: Per reference [1], "[a] value of type char is a Unicode
/// scalar value (i.e. a code point that is not a surrogate), represented
/// as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to
/// 0x10FFFF range" which contains 0x0000.
/// - `AsBytes`: `char` is per reference [1] "represented as a 32-bit
/// unsigned word" (`u32`) which is `AsBytes`. Note that unlike `u32`, not
/// all bit patterns are valid for `char`.
///
/// [1] https://doc.rust-lang.org/reference/types/textual.html
unsafe_impl!(char: FromZeroes, AsBytes);
}
safety_comment! {
/// SAFETY:
/// - `FromZeroes`, `AsBytes`, `Unaligned`: Per the reference [1], `str` has
/// the same layout as `[u8]`, and `[u8]` is `FromZeroes`, `AsBytes`, and
/// `Unaligned`.
/// - `FromZeroes`, `AsBytes`, `Unaligned`: Per the reference [1], `str`
/// has the same layout as `[u8]`, and `[u8]` is `FromZeroes`, `AsBytes`,
/// and `Unaligned`.
///
/// Note that we don't `assert_unaligned!(str)` because `assert_unaligned!`
/// uses `align_of`, which only works for `Sized` types.
///
/// TODO(#429): Add quotes from documentation.
///
/// [1] https://doc.rust-lang.org/reference/type-layout.html#str-layout
unsafe_impl!(str: FromZeroes, AsBytes, Unaligned);
}
Expand All @@ -1830,6 +1847,8 @@ safety_comment! {
/// be 0 bytes, which means that they must be 1 byte. The only valid
/// alignment for a 1-byte type is 1.
///
/// TODO(#429): Add quotes from documentation.
///
/// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
/// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
/// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
Expand Down Expand Up @@ -1860,6 +1879,8 @@ safety_comment! {
/// unthinkable that that would ever change. The only valid alignment for
/// a 1-byte type is 1.
///
/// TODO(#429): Add quotes from documentation.
///
/// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
/// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
///
Expand Down Expand Up @@ -1913,7 +1934,11 @@ safety_comment! {

safety_comment! {
/// SAFETY:
/// For all `T`, `PhantomData<T>` has size 0 and alignment 1. [1]
/// Per reference [1]:
/// "For all T, the following are guaranteed:
/// size_of::<PhantomData<T>>() == 0
/// align_of::<PhantomData<T>>() == 1".
/// This gives:
/// - `FromZeroes`, `FromBytes`: There is only one possible sequence of 0
/// bytes, and `PhantomData` is inhabited.
/// - `AsBytes`: Since `PhantomData` has size 0, it contains no padding
Expand All @@ -1935,7 +1960,11 @@ safety_comment! {
/// field, which is `pub`. Per the reference [2], this means that the
/// `#[repr(transparent)]` attribute is "considered part of the public ABI".
///
/// [1] https://doc.rust-lang.org/nightly/core/num/struct.Wrapping.html#layout-1
/// TODO(#429): Add quotes from documentation.
///
/// [1] TODO(https://doc.rust-lang.org/nightly/core/num/struct.Wrapping.html#layout-1):
/// Reference this documentation once it's available on stable.
///
/// [2] https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
unsafe_impl!(T: FromZeroes => FromZeroes for Wrapping<T>);
unsafe_impl!(T: FromBytes => FromBytes for Wrapping<T>);
Expand All @@ -1954,11 +1983,10 @@ safety_comment! {
/// Thus, we require `T: FromZeroes` and `T: FromBytes` in order to ensure
/// that `T` - and thus `MaybeUninit<T>` - contains to `UnsafeCell`s.
/// Thus, requiring that `T` implement each of these traits is sufficient
/// - `Unaligned`: `MaybeUninit<T>` is guaranteed by its documentation [1]
/// to have the same alignment as `T`.
/// - `Unaligned`: "MaybeUninit<T> is guaranteed to have the same size,
/// alignment, and ABI as T" [1]
///
/// [1]
/// https://doc.rust-lang.org/nightly/core/mem/union.MaybeUninit.html#layout-1
/// [1] https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#layout-1
///
/// TODO(https://github.com/google/zerocopy/issues/251): If we split
/// `FromBytes` and `RefFromBytes`, or if we introduce a separate
Expand Down Expand Up @@ -1988,12 +2016,14 @@ safety_comment! {
/// - `Unaligned`: `ManuallyDrop` has the same layout (and thus alignment)
/// as `T`, and `T: Unaligned` guarantees that that alignment is 1.
///
/// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
///
/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
/// validity as `T`
///
/// TODO(#429): Once this text (added in
/// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
///
/// TODO(#429):
/// - Add quotes from docs.
/// - Once [1] (added in
/// https://github.com/rust-lang/rust/pull/115522) is available on stable,
/// quote the stable docs instead of the nightly docs.
unsafe_impl!(T: ?Sized + FromZeroes => FromZeroes for ManuallyDrop<T>);
Expand Down