diff options
| author | bors <bors@rust-lang.org> | 2022-03-31 10:33:56 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-31 10:33:56 +0000 |
| commit | df20355fa9fa5e9fb89be4e4bfee8a643bb7a23e (patch) | |
| tree | 0524050d132dafc2ce53626125011a0287ea3699 | |
| parent | e730969b0d433d66d4f1c0bbd9ff70050c274ad5 (diff) | |
| parent | 2799885ed03708eea1ec372339317bd97e5c5601 (diff) | |
| download | rust-df20355fa9fa5e9fb89be4e4bfee8a643bb7a23e.tar.gz rust-df20355fa9fa5e9fb89be4e4bfee8a643bb7a23e.zip | |
Auto merge of #95456 - RalfJung:size, r=oli-obk
allow large Size again
This basically reverts most of https://github.com/rust-lang/rust/pull/80042, and instead does the panic in `bits()` with a `#[cold]` function to make sure it does not get inlined.
https://github.com/rust-lang/rust/pull/80042 added a comment about an invariant ("The top 3 bits are ALWAYS zero") that is not actually enforced, and if it were enforced that would be a problem for https://github.com/rust-lang/rust/pull/95388. So I think we should not have that invariant, and I adjusted the code accordingly.
r? `@oli-obk` Cc `@sivadeilra`
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 6082cdb78e4..52fce7c0553 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -279,7 +279,6 @@ impl ToJson for Endian { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] #[derive(HashStable_Generic)] pub struct Size { - // The top 3 bits are ALWAYS zero. raw: u64, } @@ -287,22 +286,9 @@ impl Size { pub const ZERO: Size = Size { raw: 0 }; /// Rounds `bits` up to the next-higher byte boundary, if `bits` is - /// is not aligned. + /// not a multiple of 8. pub fn from_bits(bits: impl TryInto<u64>) -> Size { let bits = bits.try_into().ok().unwrap(); - - #[cold] - fn overflow(bits: u64) -> ! { - panic!("Size::from_bits({}) has overflowed", bits); - } - - // This is the largest value of `bits` that does not cause overflow - // during rounding, and guarantees that the resulting number of bytes - // cannot cause overflow when multiplied by 8. - if bits > 0xffff_ffff_ffff_fff8 { - overflow(bits); - } - // Avoid potential overflow from `bits + 7`. Size { raw: bits / 8 + ((bits % 8) + 7) / 8 } } @@ -325,7 +311,12 @@ impl Size { #[inline] pub fn bits(self) -> u64 { - self.raw << 3 + #[cold] + fn overflow(bytes: u64) -> ! { + panic!("Size::bits: {} bytes in bits doesn't fit in u64", bytes) + } + + self.bytes().checked_mul(8).unwrap_or_else(|| overflow(self.bytes())) } #[inline] |
