[−][src]Struct rustc_mir_build::thir::pattern::_match::Slice

pub(in thir::pattern::_match) struct Slice {
    array_len: Option<u64>,
    kind: SliceKind,
}

A constructor for array and slice patterns.

Fields

array_len: Option<u64>

None if the matched value is a slice, Some(n) if it is an array of size n.

kind: SliceKind

The kind of pattern it is: fixed-length [x, y] or variable length [x, .., y].

Implementations

impl Slice[src]

pub(in thir::pattern::_match) fn new(
    array_len: Option<u64>,
    kind: SliceKind
) -> Self
[src]

pub(in thir::pattern::_match) fn arity(
    self
) -> u64
[src]

pub(in thir::pattern::_match) fn split<'p, 'tcx>(
    self,
    pcx: PatCtxt<'_, 'p, 'tcx>
) -> SmallVec<[Constructor<'tcx>; 1]>
[src]

The exhaustiveness-checking paper does not include any details on checking variable-length slice patterns. However, they may be matched by an infinite collection of fixed-length array patterns.

Checking the infinite set directly would take an infinite amount of time. However, it turns out that for each finite set of patterns P, all sufficiently large array lengths are equivalent:

Each slice s with a "sufficiently-large" length l ≥ L that applies to exactly the subset Pₜ of P can be transformed to a slice sₘ for each sufficiently-large length m that applies to exactly the same subset of P.

Because of that, each witness for reachability-checking of one of the sufficiently-large lengths can be transformed to an equally-valid witness of any other length, so we only have to check slices of the "minimal sufficiently-large length" and less.

Note that the fact that there is a single sₘ for each m not depending on the specific pattern in P is important: if you look at the pair of patterns [true, ..] [.., false] Then any slice of length ≥1 that matches one of these two patterns can be trivially turned to a slice of any other length ≥1 that matches them and vice-versa, but the slice of length 2 [false, true] that matches neither of these patterns can't be turned to a slice from length 1 that matches neither of these patterns, so we have to consider slices from length 2 there.

Now, to see that that length exists and find it, observe that slice patterns are either "fixed-length" patterns ([_, _, _]) or "variable-length" patterns ([_, .., _]).

For fixed-length patterns, all slices with lengths longer than the pattern's length have the same outcome (of not matching), so as long as L is greater than the pattern's length we can pick any sₘ from that length and get the same result.

For variable-length patterns, the situation is more complicated, because as seen above the precise value of sₘ matters.

However, for each variable-length pattern p with a prefix of length plₚ and suffix of length slₚ, only the first plₚ and the last slₚ elements are examined.

Therefore, as long as L is positive (to avoid concerns about empty types), all elements after the maximum prefix length and before the maximum suffix length are not examined by any variable-length pattern, and therefore can be added/removed without affecting them - creating equivalent patterns from any sufficiently-large length.

Of course, if fixed-length patterns exist, we must be sure that our length is large enough to miss them all, so we can pick L = max(max(FIXED_LEN)+1, max(PREFIX_LEN) + max(SUFFIX_LEN))

for example, with the above pair of patterns, all elements but the first and last can be added/removed, so any witness of length ≥2 (say, [false, false, true]) can be turned to a witness from any other length ≥2.

pub(in thir::pattern::_match) fn is_covered_by(
    self,
    other: Self
) -> bool
[src]

See Constructor::is_covered_by

Trait Implementations

impl Clone for Slice[src]

impl Copy for Slice[src]

impl Debug for Slice[src]

impl Eq for Slice[src]

impl PartialEq<Slice> for Slice[src]

impl StructuralEq for Slice[src]

impl StructuralPartialEq for Slice[src]

Auto Trait Implementations

impl RefUnwindSafe for Slice

impl Send for Slice

impl Sync for Slice

impl Unpin for Slice

impl UnwindSafe for Slice

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized, 
[src]

impl<T> Borrow<T> for T where
    T: ?Sized, 
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized, 
[src]

impl<'a, T> Captures<'a> for T where
    T: ?Sized, 
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone, 
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.