pub struct WrappingRange {
pub start: u128,
pub end: u128,
}Expand description
Inclusive wrap-around range of valid values, that is, if
start > end, it represents start..=MAX, followed by 0..=end.
That is, for an i8 primitive, a range of 254..=2 means following
sequence:
254 (-2), 255 (-1), 0, 1, 2
This is intended specifically to mirror LLVM’s !range metadata semantics.
Fields§
§start: u128§end: u128Implementations§
Source§impl WrappingRange
impl WrappingRange
pub(crate) fn debug_as(&self, size: Size, is_signed: bool) -> impl Debug
pub fn full(size: Size) -> Self
Sourcepub fn contains_range(&self, other: Self, size: Size) -> bool
pub fn contains_range(&self, other: Self, size: Size) -> bool
Returns true if all the values in other are contained in this range,
when the values are considered as having width size.
Sourcepub(crate) fn with_start(self, start: u128) -> Self
pub(crate) fn with_start(self, start: u128) -> Self
Returns self with replaced start
Sourcepub fn is_full_for(&self, size: Size) -> bool
pub fn is_full_for(&self, size: Size) -> bool
Returns true if size completely fills the range.
Note that this is not the same as self == WrappingRange::full(size).
Niche calculations can produce full ranges which are not the canonical one;
for example Option<NonZero<u16>> gets valid_range: (..=0) | (1..).
Sourcepub fn no_unsigned_wraparound(&self, size: Size) -> Result<bool, RangeFull>
pub fn no_unsigned_wraparound(&self, size: Size) -> Result<bool, RangeFull>
Checks whether this range is considered non-wrapping when the values are
interpreted as unsigned numbers of width size.
Returns Ok(true) if there’s no wrap-around, Ok(false) if there is,
and Err(..) if the range is full so it depends how you think about it.
Sourcepub fn no_signed_wraparound(&self, size: Size) -> Result<bool, RangeFull>
pub fn no_signed_wraparound(&self, size: Size) -> Result<bool, RangeFull>
Checks whether this range is considered non-wrapping when the values are
interpreted as signed numbers of width size.
This is heavily dependent on the size, as 100..=200 does wrap when
interpreted as i8, but doesn’t when interpreted as i16.
Returns Ok(true) if there’s no wrap-around, Ok(false) if there is,
and Err(..) if the range is full so it depends how you think about it.
Sourcepub fn smallest_range_containing(
values: impl IntoIterator<Item = u128>,
size: Size,
) -> Option<Self>
pub fn smallest_range_containing( values: impl IntoIterator<Item = u128>, size: Size, ) -> Option<Self>
Returns a WrappingRange that contains all of the values from the iterator,
when they’re treated as values size wide.
§Examples
use rustc_abi::{Size, WrappingRange};
let range = WrappingRange::smallest_range_containing([2, 6, 12, 4], Size::from_bytes(2));
assert_eq!(range.unwrap(), WrappingRange { start: 2, end: 12 });
let range = WrappingRange::smallest_range_containing(0..=127, Size::from_bytes(1));
assert_eq!(range.unwrap(), WrappingRange { start: 0, end: 127 });
let range = WrappingRange::smallest_range_containing([129, 128, 127], Size::from_bytes(1));
assert_eq!(range.unwrap(), WrappingRange { start: 127, end: 129 });
// The size matters because it changes where the wrapping can happen:
let range = WrappingRange::smallest_range_containing([1, 254], Size::from_bytes(1));
assert_eq!(range.unwrap(), WrappingRange { start: 254, end: 1 });
let range = WrappingRange::smallest_range_containing([1, 254], Size::from_bytes(4));
assert_eq!(range.unwrap(), WrappingRange { start: 1, end: 254 });
// Both `100..=228` and `..=228 | 100..` are the same size, but we pick the one without zero.
let range = WrappingRange::smallest_range_containing([100, 228], Size::from_bytes(1));
assert_eq!(range.unwrap(), WrappingRange { start: 100, end: 228 });
// These 4 values are evenly spaced so all 4 candidate ranges have length 193:
// `(..=32) | (96..)`, `(..=96) | (160..)`, `(..=160) | (224..)`, and `32..=224`.
// We pick the last one as the only one that doesn't contain zero.
let range = WrappingRange::smallest_range_containing([0xA0, 0xE0, 0x20, 0x60], Size::from_bytes(1));
assert_eq!(range.unwrap(), WrappingRange { start: 0x20, end: 0xE0 });Trait Implementations§
Source§impl Clone for WrappingRange
impl Clone for WrappingRange
Source§fn clone(&self) -> WrappingRange
fn clone(&self) -> WrappingRange
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for WrappingRange
Source§impl Debug for WrappingRange
impl Debug for WrappingRange
impl Eq for WrappingRange
Source§impl Hash for WrappingRange
impl Hash for WrappingRange
Source§impl PartialEq for WrappingRange
impl PartialEq for WrappingRange
Source§impl StableHash for WrappingRange
impl StableHash for WrappingRange
fn stable_hash<__Hcx: StableHashCtxt>( &self, __hcx: &mut __Hcx, __hasher: &mut StableHasher, )
impl StructuralPartialEq for WrappingRange
Auto Trait Implementations§
impl DynSend for WrappingRange
impl DynSync for WrappingRange
impl Freeze for WrappingRange
impl RefUnwindSafe for WrappingRange
impl Send for WrappingRange
impl Sync for WrappingRange
impl Unpin for WrappingRange
impl UnsafeUnpin for WrappingRange
impl UnwindSafe for WrappingRange
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
Source§fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 32 bytes