From a17a896d097796af88cc184b391159c74958b9b3 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Mon, 31 Jan 2022 12:43:15 -0800 Subject: [PATCH] Update documentation somewhat --- library/std/src/io/error.rs | 10 ++++++++ library/std/src/io/error/repr_bitpacked.rs | 28 ++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5f0a8a72c02..e901d374a6f 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -87,6 +87,16 @@ enum ErrorData { // higher already. We include it just because repr_bitpacked.rs's encoding // requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the // alignment required by the struct, only increase it). +// +// If we add more variants to ErrorData, this can be increased to 8, but it +// should probably be behind `#[cfg_attr(target_pointer_width = "64", ...)]` or +// whatever cfg we're using to enable the `repr_bitpacked` code, since only the +// that version needs the alignment, and 8 is higher than the alignment we'll +// have on 32 bit platforms. +// +// (For the sake of being explicit: the alignment requirement here only matters +// if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't +// matter at all) #[repr(align(4))] pub(crate) struct SimpleMessage { kind: ErrorKind, diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 6f7b4ac19cc..a4d29b0ce43 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -321,23 +321,26 @@ fn kind_from_prim(ek: u32) -> Option { // that our encoding relies on for correctness and soundness. (Some of these are // a bit overly thorough/cautious, admittedly) // -// If any of these are hit on a platform that libstd supports, we should just -// make sure `repr_unpacked.rs` is used instead. +// If any of these are hit on a platform that libstd supports, we should likely +// just use `repr_unpacked.rs` there instead (unless the fix is easy). macro_rules! static_assert { ($condition:expr) => { - const _: [(); 0] = [(); (!$condition) as usize]; + const _: () = assert!($condition); + }; + (@usize_eq: $lhs:expr, $rhs:expr) => { + const _: [(); $lhs] = [(); $rhs]; }; } // The bitpacking we use requires pointers be exactly 64 bits. -static_assert!(size_of::>() == 8); +static_assert!(@usize_eq: size_of::>(), 8); // We also require pointers and usize be the same size. -static_assert!(size_of::>() == size_of::()); +static_assert!(@usize_eq: size_of::>(), size_of::()); // `Custom` and `SimpleMessage` need to be thin pointers. -static_assert!(size_of::<&'static SimpleMessage>() == 8); -static_assert!(size_of::>() == 8); +static_assert!(@usize_eq: size_of::<&'static SimpleMessage>(), 8); +static_assert!(@usize_eq: size_of::>(), 8); // And they must have >= 4 byte alignment. static_assert!(align_of::() >= 4); @@ -346,12 +349,13 @@ static_assert!(align_of::() >= 4); // This is obviously true (`TAG_CUSTOM` is `0b01`), but our implementation of // `Repr::new_custom` and such would be wrong if it were not, so we check. static_assert!(size_of::() >= TAG_CUSTOM); + // These two store a payload which is allowed to be zero, so they must be // non-zero to preserve the `NonNull`'s range invariant. static_assert!(TAG_OS != 0); static_assert!(TAG_SIMPLE != 0); // We can't tag `SimpleMessage`s, the tag must be 0. -static_assert!(TAG_SIMPLE_MESSAGE == 0); +static_assert!(@usize_eq: TAG_SIMPLE_MESSAGE, 0); // Check that the point of all of this still holds. // @@ -359,7 +363,7 @@ static_assert!(TAG_SIMPLE_MESSAGE == 0); // as it's not `#[repr(transparent)]`/`#[repr(C)]`. We could add that, but // the `#[repr()]` would show up in rustdoc, which might be seen as a stable // commitment. -static_assert!(size_of::() == 8); -static_assert!(size_of::>() == 8); -static_assert!(size_of::>() == 8); -static_assert!(size_of::>() == 16); +static_assert!(@usize_eq: size_of::(), 8); +static_assert!(@usize_eq: size_of::>(), 8); +static_assert!(@usize_eq: size_of::>(), 8); +static_assert!(@usize_eq: size_of::>(), 16);