diff options
Diffstat (limited to 'compiler/rustc_abi/src')
| -rw-r--r-- | compiler/rustc_abi/src/layout.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_abi/src/lib.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_abi/src/tests.rs | 63 | 
3 files changed, 87 insertions, 10 deletions
| diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 80b44e432ee..716bb716cdb 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -313,7 +313,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> { scalar_valid_range: (Bound<u128>, Bound<u128>), discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool), discriminants: impl Iterator<Item = (VariantIdx, i128)>, - dont_niche_optimize_enum: bool, always_sized: bool, ) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> { let (present_first, present_second) = { @@ -352,13 +351,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> { // structs. (We have also handled univariant enums // that allow representation optimization.) assert!(is_enum); - self.layout_of_enum( - repr, - variants, - discr_range_of_repr, - discriminants, - dont_niche_optimize_enum, - ) + self.layout_of_enum(repr, variants, discr_range_of_repr, discriminants) } } @@ -599,7 +592,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> { variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>, discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool), discriminants: impl Iterator<Item = (VariantIdx, i128)>, - dont_niche_optimize_enum: bool, ) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> { // Until we've decided whether to use the tagged or // niche filling LayoutData, we don't want to intern the @@ -618,7 +610,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> { } let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> { - if dont_niche_optimize_enum { + if repr.inhibit_enum_layout_opt() { return None; } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 5bd73502d98..8e346706877 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1376,6 +1376,28 @@ impl WrappingRange { } } + /// Returns `true` if all the values in `other` are contained in this range, + /// when the values are considered as having width `size`. + #[inline(always)] + pub fn contains_range(&self, other: Self, size: Size) -> bool { + if self.is_full_for(size) { + true + } else { + let trunc = |x| size.truncate(x); + + let delta = self.start; + let max = trunc(self.end.wrapping_sub(delta)); + + let other_start = trunc(other.start.wrapping_sub(delta)); + let other_end = trunc(other.end.wrapping_sub(delta)); + + // Having shifted both input ranges by `delta`, now we only need to check + // whether `0..=max` contains `other_start..=other_end`, which can only + // happen if the other doesn't wrap since `self` isn't everything. + (other_start <= other_end) && (other_end <= max) + } + } + /// Returns `self` with replaced `start` #[inline(always)] fn with_start(mut self, start: u128) -> Self { diff --git a/compiler/rustc_abi/src/tests.rs b/compiler/rustc_abi/src/tests.rs index d993012378c..d49c2d44af8 100644 --- a/compiler/rustc_abi/src/tests.rs +++ b/compiler/rustc_abi/src/tests.rs @@ -5,3 +5,66 @@ fn align_constants() { assert_eq!(Align::ONE, Align::from_bytes(1).unwrap()); assert_eq!(Align::EIGHT, Align::from_bytes(8).unwrap()); } + +#[test] +fn wrapping_range_contains_range() { + let size16 = Size::from_bytes(16); + + let a = WrappingRange { start: 10, end: 20 }; + assert!(a.contains_range(a, size16)); + assert!(a.contains_range(WrappingRange { start: 11, end: 19 }, size16)); + assert!(a.contains_range(WrappingRange { start: 10, end: 10 }, size16)); + assert!(a.contains_range(WrappingRange { start: 20, end: 20 }, size16)); + assert!(!a.contains_range(WrappingRange { start: 10, end: 21 }, size16)); + assert!(!a.contains_range(WrappingRange { start: 9, end: 20 }, size16)); + assert!(!a.contains_range(WrappingRange { start: 4, end: 6 }, size16)); + assert!(!a.contains_range(WrappingRange { start: 24, end: 26 }, size16)); + + assert!(!a.contains_range(WrappingRange { start: 16, end: 14 }, size16)); + + let b = WrappingRange { start: 20, end: 10 }; + assert!(b.contains_range(b, size16)); + assert!(b.contains_range(WrappingRange { start: 20, end: 20 }, size16)); + assert!(b.contains_range(WrappingRange { start: 10, end: 10 }, size16)); + assert!(b.contains_range(WrappingRange { start: 0, end: 10 }, size16)); + assert!(b.contains_range(WrappingRange { start: 20, end: 30 }, size16)); + assert!(b.contains_range(WrappingRange { start: 20, end: 9 }, size16)); + assert!(b.contains_range(WrappingRange { start: 21, end: 10 }, size16)); + assert!(b.contains_range(WrappingRange { start: 999, end: 9999 }, size16)); + assert!(b.contains_range(WrappingRange { start: 999, end: 9 }, size16)); + assert!(!b.contains_range(WrappingRange { start: 19, end: 19 }, size16)); + assert!(!b.contains_range(WrappingRange { start: 11, end: 11 }, size16)); + assert!(!b.contains_range(WrappingRange { start: 19, end: 11 }, size16)); + assert!(!b.contains_range(WrappingRange { start: 11, end: 19 }, size16)); + + let f = WrappingRange { start: 0, end: u128::MAX }; + assert!(f.contains_range(WrappingRange { start: 10, end: 20 }, size16)); + assert!(f.contains_range(WrappingRange { start: 20, end: 10 }, size16)); + + let g = WrappingRange { start: 2, end: 1 }; + assert!(g.contains_range(WrappingRange { start: 10, end: 20 }, size16)); + assert!(g.contains_range(WrappingRange { start: 20, end: 10 }, size16)); + + let size1 = Size::from_bytes(1); + let u8r = WrappingRange { start: 0, end: 255 }; + let i8r = WrappingRange { start: 128, end: 127 }; + assert!(u8r.contains_range(i8r, size1)); + assert!(i8r.contains_range(u8r, size1)); + assert!(!u8r.contains_range(i8r, size16)); + assert!(i8r.contains_range(u8r, size16)); + + let boolr = WrappingRange { start: 0, end: 1 }; + assert!(u8r.contains_range(boolr, size1)); + assert!(i8r.contains_range(boolr, size1)); + assert!(!boolr.contains_range(u8r, size1)); + assert!(!boolr.contains_range(i8r, size1)); + + let cmpr = WrappingRange { start: 255, end: 1 }; + assert!(u8r.contains_range(cmpr, size1)); + assert!(i8r.contains_range(cmpr, size1)); + assert!(!cmpr.contains_range(u8r, size1)); + assert!(!cmpr.contains_range(i8r, size1)); + + assert!(!boolr.contains_range(cmpr, size1)); + assert!(cmpr.contains_range(boolr, size1)); +} | 
