[−][src]Struct rustc_mir_build::thir::pattern::_match::IntRange
An inclusive interval, used for precise integer exhaustiveness checking.
IntRanges always store a contiguous range. This means that values are
encoded such that 0 encodes the minimum value for the integer,
regardless of the signedness.
For example, the pattern -128..=127i8 is encoded as 0..=255.
This makes comparisons and arithmetic on interval endpoints much more
straightforward. See signed_bias for details.
IntRange is never used to encode an empty range or a "range" that wraps
around the (offset) space: i.e., range.lo <= range.hi.
Fields
range: RangeInclusive<u128>ty: Ty<'tcx>span: SpanImplementations
impl<'tcx> IntRange<'tcx>[src]
pub(in thir::pattern::_match) fn is_integral(
ty: Ty<'_>
) -> bool[src]
ty: Ty<'_>
) -> bool
pub(in thir::pattern::_match) fn is_singleton(
&self
) -> bool[src]
&self
) -> bool
pub(in thir::pattern::_match) fn boundaries(
&self
) -> (u128, u128)[src]
&self
) -> (u128, u128)
pub(in thir::pattern::_match) fn treat_exhaustively(
&self,
tcx: TyCtxt<'tcx>
) -> bool[src]
&self,
tcx: TyCtxt<'tcx>
) -> bool
Don't treat usize/isize exhaustively unless the precise_pointer_size_matching feature
is enabled.
pub(in thir::pattern::_match) fn integral_size_and_signed_bias(
tcx: TyCtxt<'tcx>,
ty: Ty<'_>
) -> Option<(Size, u128)>[src]
tcx: TyCtxt<'tcx>,
ty: Ty<'_>
) -> Option<(Size, u128)>
pub(in thir::pattern::_match) fn from_const(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
value: &Const<'tcx>,
span: Span
) -> Option<IntRange<'tcx>>[src]
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
value: &Const<'tcx>,
span: Span
) -> Option<IntRange<'tcx>>
pub(in thir::pattern::_match) fn from_range(
tcx: TyCtxt<'tcx>,
lo: u128,
hi: u128,
ty: Ty<'tcx>,
end: &RangeEnd,
span: Span
) -> Option<IntRange<'tcx>>[src]
tcx: TyCtxt<'tcx>,
lo: u128,
hi: u128,
ty: Ty<'tcx>,
end: &RangeEnd,
span: Span
) -> Option<IntRange<'tcx>>
pub(in thir::pattern::_match) fn signed_bias(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>
) -> u128[src]
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>
) -> u128
pub(in thir::pattern::_match) fn is_subrange(
&self,
other: &Self
) -> bool[src]
&self,
other: &Self
) -> bool
pub(in thir::pattern::_match) fn intersection(
&self,
tcx: TyCtxt<'tcx>,
other: &Self
) -> Option<Self>[src]
&self,
tcx: TyCtxt<'tcx>,
other: &Self
) -> Option<Self>
pub(in thir::pattern::_match) fn suspicious_intersection(
&self,
other: &Self
) -> bool[src]
&self,
other: &Self
) -> bool
pub(in thir::pattern::_match) fn to_pat(
&self,
tcx: TyCtxt<'tcx>
) -> Pat<'tcx>[src]
&self,
tcx: TyCtxt<'tcx>
) -> Pat<'tcx>
pub(in thir::pattern::_match) fn split<'p>(
&self,
pcx: PatCtxt<'_, 'p, 'tcx>,
hir_id: Option<HirId>
) -> SmallVec<[Constructor<'tcx>; 1]>[src]
&self,
pcx: PatCtxt<'_, 'p, 'tcx>,
hir_id: Option<HirId>
) -> SmallVec<[Constructor<'tcx>; 1]>
For exhaustive integer matching, some constructors are grouped within other constructors
(namely integer typed values are grouped within ranges). However, when specialising these
constructors, we want to be specialising for the underlying constructors (the integers), not
the groups (the ranges). Thus we need to split the groups up. Splitting them up naïvely would
mean creating a separate constructor for every single value in the range, which is clearly
impractical. However, observe that for some ranges of integers, the specialisation will be
identical across all values in that range (i.e., there are equivalence classes of ranges of
constructors based on their U(S(c, P), S(c, p)) outcome). These classes are grouped by
the patterns that apply to them (in the matrix P). We can split the range whenever the
patterns that apply to that range (specifically: the patterns that intersect with that range)
change.
Our solution, therefore, is to split the range constructor into subranges at every single point
the group of intersecting patterns changes (using the method described below).
And voilà! We're testing precisely those ranges that we need to, without any exhaustive matching
on actual integers. The nice thing about this is that the number of subranges is linear in the
number of rows in the matrix (i.e., the number of cases in the match statement), so we don't
need to be worried about matching over gargantuan ranges.
Essentially, given the first column of a matrix representing ranges, looking like the following:
|------| |----------| |-------| || |-------| |-------| |----| || |---------|
We split the ranges up into equivalence classes so the ranges are no longer overlapping:
|--|--|||-||||--||---|||-------| |-|||| ||
The logic for determining how to split the ranges is fairly straightforward: we calculate boundaries for each interval range, sort them, then create constructors for each new interval between every pair of boundary points. (This essentially sums up to performing the intuitive merging operation depicted above.)
pub(in thir::pattern::_match) fn lint_overlapping_patterns(
&self,
tcx: TyCtxt<'tcx>,
hir_id: Option<HirId>,
ty: Ty<'tcx>,
overlaps: Vec<IntRange<'tcx>>
)[src]
&self,
tcx: TyCtxt<'tcx>,
hir_id: Option<HirId>,
ty: Ty<'tcx>,
overlaps: Vec<IntRange<'tcx>>
)
pub(in thir::pattern::_match) fn is_covered_by<'p>(
&self,
pcx: PatCtxt<'_, 'p, 'tcx>,
other: &Self
) -> bool[src]
&self,
pcx: PatCtxt<'_, 'p, 'tcx>,
other: &Self
) -> bool
See Constructor::is_covered_by
Trait Implementations
impl<'tcx> Clone for IntRange<'tcx>[src]
impl<'tcx> Debug for IntRange<'tcx>[src]
impl<'tcx> PartialEq<IntRange<'tcx>> for IntRange<'tcx>[src]
Ignore spans when comparing, they don't carry semantic information as they are only for lints.
Auto Trait Implementations
impl<'tcx> !RefUnwindSafe for IntRange<'tcx>
impl<'tcx> !Send for IntRange<'tcx>
impl<'tcx> !Sync for IntRange<'tcx>
impl<'tcx> Unpin for IntRange<'tcx>
impl<'tcx> !UnwindSafe for IntRange<'tcx>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized, [src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized, [src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T[src]
impl<'a, T> Captures<'a> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> From<T> for T[src]
impl<T, U> Into<U> for T where
U: From<T>, [src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone, [src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T[src]
pub fn clone_into(&self, target: &mut T)[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>, [src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>, [src]
U: TryFrom<T>,