/// Note: most tests relevant to this file can be found (at the time of writing)
/// in src/tests/ui/pattern/usefulness.
///
/// This file includes the logic for exhaustiveness and usefulness checking for
/// pattern-matching. Specifically, given a list of patterns for a type, we can
/// tell whether:
/// (a) the patterns cover every possible constructor for the type [exhaustiveness]
/// (b) each pattern is necessary [usefulness]
///
/// The algorithm implemented here is a modified version of the one described in:
/// http://moscova.inria.fr/~maranget/papers/warn/index.html
/// However, to save future implementors from reading the original paper, we
/// summarise the algorithm here to hopefully save time and be a little clearer
/// (without being so rigorous).
///
/// The core of the algorithm revolves about a "usefulness" check. In particular, we
/// are trying to compute a predicate `U(P, p)` where `P` is a list of patterns (we refer to this as
/// a matrix). `U(P, p)` represents whether, given an existing list of patterns
/// `P_1 ..= P_m`, adding a new pattern `p` will be "useful" (that is, cover previously-
/// uncovered values of the type).
///
/// If we have this predicate, then we can easily compute both exhaustiveness of an
/// entire set of patterns and the individual usefulness of each one.
/// (a) the set of patterns is exhaustive iff `U(P, _)` is false (i.e., adding a wildcard
/// match doesn't increase the number of values we're matching)
/// (b) a pattern `P_i` is not useful if `U(P[0..=(i-1), P_i)` is false (i.e., adding a
/// pattern to those that have come before it doesn't increase the number of values
/// we're matching).
///
/// During the course of the algorithm, the rows of the matrix won't just be individual patterns,
/// but rather partially-deconstructed patterns in the form of a list of patterns. The paper
/// calls those pattern-vectors, and we will call them pattern-stacks. The same holds for the
/// new pattern `p`.
///
/// For example, say we have the following:
/// ```
///     // x: (Option<bool>, Result<()>)
///     match x {
///         (Some(true), _) => {}
///         (None, Err(())) => {}
///         (None, Err(_)) => {}
///     }
/// ```
/// Here, the matrix `P` starts as:
/// [
///     [(Some(true), _)],
///     [(None, Err(()))],
///     [(None, Err(_))],
/// ]
/// We can tell it's not exhaustive, because `U(P, _)` is true (we're not covering
/// `[(Some(false), _)]`, for instance). In addition, row 3 is not useful, because
/// all the values it covers are already covered by row 2.
///
/// A list of patterns can be thought of as a stack, because we are mainly interested in the top of
/// the stack at any given point, and we can pop or apply constructors to get new pattern-stacks.
/// To match the paper, the top of the stack is at the beginning / on the left.
///
/// There are two important operations on pattern-stacks necessary to understand the algorithm:
///     1. We can pop a given constructor off the top of a stack. This operation is called
///        `specialize`, and is denoted `S(c, p)` where `c` is a constructor (like `Some` or
///        `None`) and `p` a pattern-stack.
///        If the pattern on top of the stack can cover `c`, this removes the constructor and
///        pushes its arguments onto the stack. It also expands OR-patterns into distinct patterns.
///        Otherwise the pattern-stack is discarded.
///        This essentially filters those pattern-stacks whose top covers the constructor `c` and
///        discards the others.
///
///        For example, the first pattern above initially gives a stack `[(Some(true), _)]`. If we
///        pop the tuple constructor, we are left with `[Some(true), _]`, and if we then pop the
///        `Some` constructor we get `[true, _]`. If we had popped `None` instead, we would get
///        nothing back.
///
///        This returns zero or more new pattern-stacks, as follows. We look at the pattern `p_1`
///        on top of the stack, and we have four cases:
///             1.1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We
///                  push onto the stack the arguments of this constructor, and return the result:
///                     r_1, .., r_a, p_2, .., p_n
///             1.2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and
///                  return nothing.
///             1.3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c` has
///                  arguments (its arity), and return the resulting stack:
///                     _, .., _, p_2, .., p_n
///             1.4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
///                  stack:
///                     S(c, (r_1, p_2, .., p_n))
///                     S(c, (r_2, p_2, .., p_n))
///
///     2. We can pop a wildcard off the top of the stack. This is called `D(p)`, where `p` is
///        a pattern-stack.
///        This is used when we know there are missing constructor cases, but there might be
///        existing wildcard patterns, so to check the usefulness of the matrix, we have to check
///        all its *other* components.
///
///        It is computed as follows. We look at the pattern `p_1` on top of the stack,
///        and we have three cases:
///             1.1. `p_1 = c(r_1, .., r_a)`. We discard the current stack and return nothing.
///             1.2. `p_1 = _`. We return the rest of the stack:
///                     p_2, .., p_n
///             1.3. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
///               stack.
///                     D((r_1, p_2, .., p_n))
///                     D((r_2, p_2, .., p_n))
///
///     Note that the OR-patterns are not always used directly in Rust, but are used to derive the
///     exhaustive integer matching rules, so they're written here for posterity.
///
/// Both those operations extend straightforwardly to a list or pattern-stacks, i.e. a matrix, by
/// working row-by-row. Popping a constructor ends up keeping only the matrix rows that start with
/// the given constructor, and popping a wildcard keeps those rows that start with a wildcard.
///
///
/// The algorithm for computing `U`
/// -------------------------------
/// The algorithm is inductive (on the number of columns: i.e., components of tuple patterns).
/// That means we're going to check the components from left-to-right, so the algorithm
/// operates principally on the first component of the matrix and new pattern-stack `p`.
/// This algorithm is realised in the `is_useful` function.
///
/// Base case. (`n = 0`, i.e., an empty tuple pattern)
///     - If `P` already contains an empty pattern (i.e., if the number of patterns `m > 0`),
///       then `U(P, p)` is false.
///     - Otherwise, `P` must be empty, so `U(P, p)` is true.
///
/// Inductive step. (`n > 0`, i.e., whether there's at least one column
///                  [which may then be expanded into further columns later])
///     We're going to match on the top of the new pattern-stack, `p_1`.
///         - If `p_1 == c(r_1, .., r_a)`, i.e. we have a constructor pattern.
///           Then, the usefulness of `p_1` can be reduced to whether it is useful when
///           we ignore all the patterns in the first column of `P` that involve other constructors.
///           This is where `S(c, P)` comes in:
///           `U(P, p) := U(S(c, P), S(c, p))`
///           This special case is handled in `is_useful_specialized`.
///
///           For example, if `P` is:
///           [
///               [Some(true), _],
///               [None, 0],
///           ]
///           and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
///           matches values that row 2 doesn't. For row 1 however, we need to dig into the
///           arguments of `Some` to know whether some new value is covered. So we compute
///           `U([[true, _]], [false, 0])`.
///
///         - If `p_1 == _`, then we look at the list of constructors that appear in the first
///               component of the rows of `P`:
///             + If there are some constructors that aren't present, then we might think that the
///               wildcard `_` is useful, since it covers those constructors that weren't covered
///               before.
///               That's almost correct, but only works if there were no wildcards in those first
///               components. So we need to check that `p` is useful with respect to the rows that
///               start with a wildcard, if there are any. This is where `D` comes in:
///               `U(P, p) := U(D(P), D(p))`
///
///               For example, if `P` is:
///               [
///                   [_, true, _],
///                   [None, false, 1],
///               ]
///               and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
///               only had row 2, we'd know that `p` is useful. However row 1 starts with a
///               wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
///
///             + Otherwise, all possible constructors (for the relevant type) are present. In this
///               case we must check whether the wildcard pattern covers any unmatched value. For
///               that, we can think of the `_` pattern as a big OR-pattern that covers all
///               possible constructors. For `Option`, that would mean `_ = None | Some(_)` for
///               example. The wildcard pattern is useful in this case if it is useful when
///               specialized to one of the possible constructors. So we compute:
///               `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
///
///               For example, if `P` is:
///               [
///                   [Some(true), _],
///                   [None, false],
///               ]
///               and `p` is [_, false], both `None` and `Some` constructors appear in the first
///               components of `P`. We will therefore try popping both constructors in turn: we
///               compute U([[true, _]], [_, false]) for the `Some` constructor, and U([[false]],
///               [false]) for the `None` constructor. The first case returns true, so we know that
///               `p` is useful for `P`. Indeed, it matches `[Some(false), _]` that wasn't matched
///               before.
///
///         - If `p_1 == r_1 | r_2`, then the usefulness depends on each `r_i` separately:
///           `U(P, p) := U(P, (r_1, p_2, .., p_n))
///                    || U(P, (r_2, p_2, .., p_n))`
///
/// Modifications to the algorithm
/// ------------------------------
/// The algorithm in the paper doesn't cover some of the special cases that arise in Rust, for
/// example uninhabited types and variable-length slice patterns. These are drawn attention to
/// throughout the code below. I'll make a quick note here about how exhaustive integer matching is
/// accounted for, though.
///
/// Exhaustive integer matching
/// ---------------------------
/// An integer type can be thought of as a (huge) sum type: 1 | 2 | 3 | ...
/// So to support exhaustive integer matching, we can make use of the logic in the paper for
/// OR-patterns. However, we obviously can't just treat ranges x..=y as individual sums, because
/// they are likely gigantic. So we instead treat ranges as constructors of the integers. This means
/// that we have a constructor *of* constructors (the integers themselves). We then need to work
/// through all the inductive step rules above, deriving how the ranges would be treated as
/// OR-patterns, and making sure that they're treated in the same way even when they're ranges.
/// There are really only four special cases here:
/// - When we match on a constructor that's actually a range, we have to treat it as if we would
///   an OR-pattern.
///     + It turns out that we can simply extend the case for single-value patterns in
///      `specialize` to either be *equal* to a value constructor, or *contained within* a range
///      constructor.
///     + When the pattern itself is a range, you just want to tell whether any of the values in
///       the pattern range coincide with values in the constructor range, which is precisely
///       intersection.
///   Since when encountering a range pattern for a value constructor, we also use inclusion, it
///   means that whenever the constructor is a value/range and the pattern is also a value/range,
///   we can simply use intersection to test usefulness.
/// - When we're testing for usefulness of a pattern and the pattern's first component is a
///   wildcard.
///     + If all the constructors appear in the matrix, we have a slight complication. By default,
///       the behaviour (i.e., a disjunction over specialised matrices for each constructor) is
///       invalid, because we want a disjunction over every *integer* in each range, not just a
///       disjunction over every range. This is a bit more tricky to deal with: essentially we need
///       to form equivalence classes of subranges of the constructor range for which the behaviour
///       of the matrix `P` and new pattern `p` are the same. This is described in more
///       detail in `split_grouped_constructors`.
///     + If some constructors are missing from the matrix, it turns out we don't need to do
///       anything special (because we know none of the integers are actually wildcards: i.e., we
///       can't span wildcards using ranges).
use self::Constructor::*;
use self::SliceKind::*;
use self::Usefulness::*;
use self::WitnessPreference::*;

use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;

use super::{compare_const_vals, PatternFoldable, PatternFolder};
use super::{FieldPat, Pat, PatKind, PatRange};

use rustc::ty::layout::{Integer, IntegerExt, Size, VariantIdx};
use rustc::ty::{self, Const, Ty, TyCtxt, TypeFoldable, VariantDef};
use rustc_hir::def_id::DefId;
use rustc_hir::{HirId, RangeEnd};

use rustc::lint;
use rustc::mir::interpret::{truncate, AllocId, ConstValue, Pointer, Scalar};
use rustc::mir::Field;
use rustc::util::common::ErrorReported;

use rustc_span::{Span, DUMMY_SP};
use syntax::attr::{SignedInt, UnsignedInt};

use arena::TypedArena;

use smallvec::{smallvec, SmallVec};
use std::borrow::Cow;
use std::cmp::{self, max, min, Ordering};
use std::convert::TryInto;
use std::fmt;
use std::iter::{FromIterator, IntoIterator};
use std::ops::RangeInclusive;
use std::u128;

crate fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pat<'tcx>) -> Pat<'tcx> {
    LiteralExpander { tcx: cx.tcx, param_env: cx.param_env }.fold_pattern(&pat)
}

struct LiteralExpander<'tcx> {
    tcx: TyCtxt<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
}

impl<'tcx> LiteralExpander<'tcx> {
    /// Derefs `val` and potentially unsizes the value if `crty` is an array and `rty` a slice.
    ///
    /// `crty` and `rty` can differ because you can use array constants in the presence of slice
    /// patterns. So the pattern may end up being a slice, but the constant is an array. We convert
    /// the array to a slice in that case.
    fn fold_const_value_deref(
        &mut self,
        val: ConstValue<'tcx>,
        // the pattern's pointee type
        rty: Ty<'tcx>,
        // the constant's pointee type
        crty: Ty<'tcx>,
    ) -> ConstValue<'tcx> {
        debug!("fold_const_value_deref {:?} {:?} {:?}", val, rty, crty);
        match (val, &crty.kind, &rty.kind) {
            // the easy case, deref a reference
            (ConstValue::Scalar(p), x, y) if x == y => {
                match p {
                    Scalar::Ptr(p) => {
                        let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id);
                        ConstValue::ByRef { alloc, offset: p.offset }
                    }
                    Scalar::Raw { .. } => {
                        let layout = self.tcx.layout_of(self.param_env.and(rty)).unwrap();
                        if layout.is_zst() {
                            // Deref of a reference to a ZST is a nop.
                            ConstValue::Scalar(Scalar::zst())
                        } else {
                            // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;`
                            bug!("cannot deref {:#?}, {} -> {}", val, crty, rty);
                        }
                    }
                }
            }
            // unsize array to slice if pattern is array but match value or other patterns are slice
            (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
                assert_eq!(t, u);
                ConstValue::Slice {
                    data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
                    start: p.offset.bytes().try_into().unwrap(),
                    end: n.eval_usize(self.tcx, ty::ParamEnv::empty()).try_into().unwrap(),
                }
            }
            // fat pointers stay the same
            (ConstValue::Slice { .. }, _, _)
            | (_, ty::Slice(_), ty::Slice(_))
            | (_, ty::Str, ty::Str) => val,
            // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used
            _ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),
        }
    }
}

impl<'tcx> PatternFolder<'tcx> for LiteralExpander<'tcx> {
    fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> {
        debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.kind, pat.kind);
        match (&pat.ty.kind, &*pat.kind) {
            (
                &ty::Ref(_, rty, _),
                &PatKind::Constant {
                    value:
                        Const {
                            val: ty::ConstKind::Value(val),
                            ty: ty::TyS { kind: ty::Ref(_, crty, _), .. },
                        },
                },
            ) => Pat {
                ty: pat.ty,
                span: pat.span,
                kind: box PatKind::Deref {
                    subpattern: Pat {
                        ty: rty,
                        span: pat.span,
                        kind: box PatKind::Constant {
                            value: self.tcx.mk_const(Const {
                                val: ty::ConstKind::Value(
                                    self.fold_const_value_deref(*val, rty, crty),
                                ),
                                ty: rty,
                            }),
                        },
                    },
                },
            },

            (
                &ty::Ref(_, rty, _),
                &PatKind::Constant {
                    value: Const { val, ty: ty::TyS { kind: ty::Ref(_, crty, _), .. } },
                },
            ) => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),

            (_, &PatKind::Binding { subpattern: Some(ref s), .. }) => s.fold_with(self),
            (_, &PatKind::AscribeUserType { subpattern: ref s, .. }) => s.fold_with(self),
            _ => pat.super_fold_with(self),
        }
    }
}

impl<'tcx> Pat<'tcx> {
    pub(super) fn is_wildcard(&self) -> bool {
        match *self.kind {
            PatKind::Binding { subpattern: None, .. } | PatKind::Wild => true,
            _ => false,
        }
    }
}

/// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
/// works well.
#[derive(Debug, Clone)]
crate struct PatStack<'p, 'tcx>(SmallVec<[&'p Pat<'tcx>; 2]>);

impl<'p, 'tcx> PatStack<'p, 'tcx> {
    crate fn from_pattern(pat: &'p Pat<'tcx>) -> Self {
        PatStack(smallvec![pat])
    }

    fn from_vec(vec: SmallVec<[&'p Pat<'tcx>; 2]>) -> Self {
        PatStack(vec)
    }

    fn from_slice(s: &[&'p Pat<'tcx>]) -> Self {
        PatStack(SmallVec::from_slice(s))
    }

    fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    fn len(&self) -> usize {
        self.0.len()
    }

    fn head(&self) -> &'p Pat<'tcx> {
        self.0[0]
    }

    fn to_tail(&self) -> Self {
        PatStack::from_slice(&self.0[1..])
    }

    fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> {
        self.0.iter().map(|p| *p)
    }

    // If the first pattern is an or-pattern, expand this pattern. Otherwise, return `None`.
    fn expand_or_pat(&self) -> Option<Vec<Self>> {
        if self.is_empty() {
            None
        } else if let PatKind::Or { pats } = &*self.head().kind {
            Some(
                pats.iter()
                    .map(|pat| {
                        let mut new_patstack = PatStack::from_pattern(pat);
                        new_patstack.0.extend_from_slice(&self.0[1..]);
                        new_patstack
                    })
                    .collect(),
            )
        } else {
            None
        }
    }

    /// This computes `D(self)`. See top of the file for explanations.
    fn specialize_wildcard(&self) -> Option<Self> {
        if self.head().is_wildcard() { Some(self.to_tail()) } else { None }
    }

    /// This computes `S(constructor, self)`. See top of the file for explanations.
    fn specialize_constructor(
        &self,
        cx: &mut MatchCheckCtxt<'p, 'tcx>,
        constructor: &Constructor<'tcx>,
        ctor_wild_subpatterns: &'p [Pat<'tcx>],
    ) -> Option<PatStack<'p, 'tcx>> {
        let new_heads = specialize_one_pattern(cx, self.head(), constructor, ctor_wild_subpatterns);
        new_heads.map(|mut new_head| {
            new_head.0.extend_from_slice(&self.0[1..]);
            new_head
        })
    }
}

impl<'p, 'tcx> Default for PatStack<'p, 'tcx> {
    fn default() -> Self {
        PatStack(smallvec![])
    }
}

impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> {
    fn from_iter<T>(iter: T) -> Self
    where
        T: IntoIterator<Item = &'p Pat<'tcx>>,
    {
        PatStack(iter.into_iter().collect())
    }
}

/// A 2D matrix.
#[derive(Clone)]
crate struct Matrix<'p, 'tcx>(Vec<PatStack<'p, 'tcx>>);

impl<'p, 'tcx> Matrix<'p, 'tcx> {
    crate fn empty() -> Self {
        Matrix(vec![])
    }

    /// Pushes a new row to the matrix. If the row starts with an or-pattern, this expands it.
    crate fn push(&mut self, row: PatStack<'p, 'tcx>) {
        if let Some(rows) = row.expand_or_pat() {
            self.0.extend(rows);
        } else {
            self.0.push(row);
        }
    }

    /// Iterate over the first component of each row
    fn heads<'a>(&'a self) -> impl Iterator<Item = &'a Pat<'tcx>> + Captures<'p> {
        self.0.iter().map(|r| r.head())
    }

    /// This computes `D(self)`. See top of the file for explanations.
    fn specialize_wildcard(&self) -> Self {
        self.0.iter().filter_map(|r| r.specialize_wildcard()).collect()
    }

    /// This computes `S(constructor, self)`. See top of the file for explanations.
    fn specialize_constructor(
        &self,
        cx: &mut MatchCheckCtxt<'p, 'tcx>,
        constructor: &Constructor<'tcx>,
        ctor_wild_subpatterns: &'p [Pat<'tcx>],
    ) -> Matrix<'p, 'tcx> {
        self.0
            .iter()
            .filter_map(|r| r.specialize_constructor(cx, constructor, ctor_wild_subpatterns))
            .collect()
    }
}

/// Pretty-printer for matrices of patterns, example:
/// +++++++++++++++++++++++++++++
/// + _     + []                +
/// +++++++++++++++++++++++++++++
/// + true  + [First]           +
/// +++++++++++++++++++++++++++++
/// + true  + [Second(true)]    +
/// +++++++++++++++++++++++++++++
/// + false + [_]               +
/// +++++++++++++++++++++++++++++
/// + _     + [_, _, tail @ ..] +
/// +++++++++++++++++++++++++++++
impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "\n")?;

        let &Matrix(ref m) = self;
        let pretty_printed_matrix: Vec<Vec<String>> =
            m.iter().map(|row| row.iter().map(|pat| format!("{:?}", pat)).collect()).collect();

        let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0);
        assert!(m.iter().all(|row| row.len() == column_count));
        let column_widths: Vec<usize> = (0..column_count)
            .map(|col| pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0))
            .collect();

        let total_width = column_widths.iter().cloned().sum::<usize>() + column_count * 3 + 1;
        let br = "+".repeat(total_width);
        write!(f, "{}\n", br)?;
        for row in pretty_printed_matrix {
            write!(f, "+")?;
            for (column, pat_str) in row.into_iter().enumerate() {
                write!(f, " ")?;
                write!(f, "{:1$}", pat_str, column_widths[column])?;
                write!(f, " +")?;
            }
            write!(f, "\n")?;
            write!(f, "{}\n", br)?;
        }
        Ok(())
    }
}

impl<'p, 'tcx> FromIterator<PatStack<'p, 'tcx>> for Matrix<'p, 'tcx> {
    fn from_iter<T>(iter: T) -> Self
    where
        T: IntoIterator<Item = PatStack<'p, 'tcx>>,
    {
        let mut matrix = Matrix::empty();
        for x in iter {
            // Using `push` ensures we correctly expand or-patterns.
            matrix.push(x);
        }
        matrix
    }
}

crate struct MatchCheckCtxt<'a, 'tcx> {
    crate tcx: TyCtxt<'tcx>,
    /// The module in which the match occurs. This is necessary for
    /// checking inhabited-ness of types because whether a type is (visibly)
    /// inhabited can depend on whether it was defined in the current module or
    /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty
    /// outside it's module and should not be matchable with an empty match
    /// statement.
    crate module: DefId,
    param_env: ty::ParamEnv<'tcx>,
    crate pattern_arena: &'a TypedArena<Pat<'tcx>>,
}

impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
    crate fn create_and_enter<R>(
        tcx: TyCtxt<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        module: DefId,
        f: impl for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
    ) -> R {
        let pattern_arena = TypedArena::default();

        f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
    }

    fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
        if self.tcx.features().exhaustive_patterns {
            self.tcx.is_ty_uninhabited_from(self.module, ty)
        } else {
            false
        }
    }

    // Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
    crate fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
        match ty.kind {
            ty::Adt(def, ..) => {
                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did.is_local()
            }
            _ => false,
        }
    }

    // Returns whether the given variant is from another crate and has its fields declared
    // `#[non_exhaustive]`.
    fn is_foreign_non_exhaustive_variant(&self, ty: Ty<'tcx>, variant: &VariantDef) -> bool {
        match ty.kind {
            ty::Adt(def, ..) => variant.is_field_list_non_exhaustive() && !def.did.is_local(),
            _ => false,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum SliceKind {
    /// Patterns of length `n` (`[x, y]`).
    FixedLen(u64),
    /// Patterns using the `..` notation (`[x, .., y]`).
    /// Captures any array constructor of `length >= i + j`.
    /// In the case where `array_len` is `Some(_)`,
    /// this indicates that we only care about the first `i` and the last `j` values of the array,
    /// and everything in between is a wildcard `_`.
    VarLen(u64, u64),
}

impl SliceKind {
    fn arity(self) -> u64 {
        match self {
            FixedLen(length) => length,
            VarLen(prefix, suffix) => prefix + suffix,
        }
    }

    /// Whether this pattern includes patterns of length `other_len`.
    fn covers_length(self, other_len: u64) -> bool {
        match self {
            FixedLen(len) => len == other_len,
            VarLen(prefix, suffix) => prefix + suffix <= other_len,
        }
    }

    /// Returns a collection of slices that spans the values covered by `self`, subtracted by the
    /// values covered by `other`: i.e., `self \ other` (in set notation).
    fn subtract(self, other: Self) -> SmallVec<[Self; 1]> {
        // Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
        // Naming: we remove the "neg" constructors from the "pos" ones.
        match self {
            FixedLen(pos_len) => {
                if other.covers_length(pos_len) {
                    smallvec![]
                } else {
                    smallvec![self]
                }
            }
            VarLen(pos_prefix, pos_suffix) => {
                let pos_len = pos_prefix + pos_suffix;
                match other {
                    FixedLen(neg_len) => {
                        if neg_len < pos_len {
                            smallvec![self]
                        } else {
                            (pos_len..neg_len)
                                .map(FixedLen)
                                // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
                                .chain(Some(VarLen(neg_len + 1 - pos_suffix, pos_suffix)))
                                .collect()
                        }
                    }
                    VarLen(neg_prefix, neg_suffix) => {
                        let neg_len = neg_prefix + neg_suffix;
                        if neg_len <= pos_len {
                            smallvec![]
                        } else {
                            (pos_len..neg_len).map(FixedLen).collect()
                        }
                    }
                }
            }
        }
    }
}

/// A constructor for array and slice patterns.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct Slice {
    /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
    array_len: Option<u64>,
    /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
    kind: SliceKind,
}

impl Slice {
    /// Returns what patterns this constructor covers: either fixed-length patterns or
    /// variable-length patterns.
    fn pattern_kind(self) -> SliceKind {
        match self {
            Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
                if prefix + suffix == len =>
            {
                FixedLen(len)
            }
            _ => self.kind,
        }
    }

    /// Returns what values this constructor covers: either values of only one given length, or
    /// values of length above a given length.
    /// This is different from `pattern_kind()` because in some cases the pattern only takes into
    /// account a subset of the entries of the array, but still only captures values of a given
    /// length.
    fn value_kind(self) -> SliceKind {
        match self {
            Slice { array_len: Some(len), kind: VarLen(_, _) } => FixedLen(len),
            _ => self.kind,
        }
    }

    fn arity(self) -> u64 {
        self.pattern_kind().arity()
    }
}

#[derive(Clone, Debug, PartialEq)]
enum Constructor<'tcx> {
    /// The constructor of all patterns that don't vary by constructor,
    /// e.g., struct patterns and fixed-length arrays.
    Single,
    /// Enum variants.
    Variant(DefId),
    /// Literal values.
    ConstantValue(&'tcx ty::Const<'tcx>),
    /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
    IntRange(IntRange<'tcx>),
    /// Ranges of floating-point literal values (`2.0..=5.2`).
    FloatRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
    /// Array and slice patterns.
    Slice(Slice),
    /// Fake extra constructor for enums that aren't allowed to be matched exhaustively.
    NonExhaustive,
}

impl<'tcx> Constructor<'tcx> {
    fn is_slice(&self) -> bool {
        match self {
            Slice(_) => true,
            _ => false,
        }
    }

    fn variant_index_for_adt<'a>(
        &self,
        cx: &MatchCheckCtxt<'a, 'tcx>,
        adt: &'tcx ty::AdtDef,
    ) -> VariantIdx {
        match *self {
            Variant(id) => adt.variant_index_with_id(id),
            Single => {
                assert!(!adt.is_enum());
                VariantIdx::new(0)
            }
            ConstantValue(c) => cx.tcx.destructure_const(cx.param_env.and(c)).variant,
            _ => bug!("bad constructor {:?} for adt {:?}", self, adt),
        }
    }

    // Returns the set of constructors covered by `self` but not by
    // anything in `other_ctors`.
    fn subtract_ctors(&self, other_ctors: &Vec<Constructor<'tcx>>) -> Vec<Constructor<'tcx>> {
        if other_ctors.is_empty() {
            return vec![self.clone()];
        }

        match self {
            // Those constructors can only match themselves.
            Single | Variant(_) | ConstantValue(..) | FloatRange(..) => {
                if other_ctors.iter().any(|c| c == self) { vec![] } else { vec![self.clone()] }
            }
            &Slice(slice) => {
                let mut other_slices = other_ctors
                    .iter()
                    .filter_map(|c: &Constructor<'_>| match c {
                        Slice(slice) => Some(*slice),
                        // FIXME(oli-obk): implement `deref` for `ConstValue`
                        ConstantValue(..) => None,
                        _ => bug!("bad slice pattern constructor {:?}", c),
                    })
                    .map(Slice::value_kind);

                match slice.value_kind() {
                    FixedLen(self_len) => {
                        if other_slices.any(|other_slice| other_slice.covers_length(self_len)) {
                            vec![]
                        } else {
                            vec![Slice(slice)]
                        }
                    }
                    kind @ VarLen(..) => {
                        let mut remaining_slices = vec![kind];

                        // For each used slice, subtract from the current set of slices.
                        for other_slice in other_slices {
                            remaining_slices = remaining_slices
                                .into_iter()
                                .flat_map(|remaining_slice| remaining_slice.subtract(other_slice))
                                .collect();

                            // If the constructors that have been considered so far already cover
                            // the entire range of `self`, no need to look at more constructors.
                            if remaining_slices.is_empty() {
                                break;
                            }
                        }

                        remaining_slices
                            .into_iter()
                            .map(|kind| Slice { array_len: slice.array_len, kind })
                            .map(Slice)
                            .collect()
                    }
                }
            }
            IntRange(self_range) => {
                let mut remaining_ranges = vec![self_range.clone()];
                for other_ctor in other_ctors {
                    if let IntRange(other_range) = other_ctor {
                        if other_range == self_range {
                            // If the `self` range appears directly in a `match` arm, we can
                            // eliminate it straight away.
                            remaining_ranges = vec![];
                        } else {
                            // Otherwise explicitely compute the remaining ranges.
                            remaining_ranges = other_range.subtract_from(remaining_ranges);
                        }

                        // If the ranges that have been considered so far already cover the entire
                        // range of values, we can return early.
                        if remaining_ranges.is_empty() {
                            break;
                        }
                    }
                }

                // Convert the ranges back into constructors.
                remaining_ranges.into_iter().map(IntRange).collect()
            }
            // This constructor is never covered by anything else
            NonExhaustive => vec![NonExhaustive],
        }
    }

    /// This returns one wildcard pattern for each argument to this constructor.
    ///
    /// This must be consistent with `apply`, `specialize_one_pattern`, and `arity`.
    fn wildcard_subpatterns<'a>(
        &self,
        cx: &MatchCheckCtxt<'a, 'tcx>,
        ty: Ty<'tcx>,
    ) -> Vec<Pat<'tcx>> {
        debug!("wildcard_subpatterns({:#?}, {:?})", self, ty);

        match self {
            Single | Variant(_) => match ty.kind {
                ty::Tuple(ref fs) => {
                    fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect()
                }
                ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)],
                ty::Adt(adt, substs) => {
                    if adt.is_box() {
                        // Use T as the sub pattern type of Box<T>.
                        vec![Pat::wildcard_from_ty(substs.type_at(0))]
                    } else {
                        let variant = &adt.variants[self.variant_index_for_adt(cx, adt)];
                        let is_non_exhaustive = cx.is_foreign_non_exhaustive_variant(ty, variant);
                        variant
                            .fields
                            .iter()
                            .map(|field| {
                                let is_visible = adt.is_enum()
                                    || field.vis.is_accessible_from(cx.module, cx.tcx);
                                let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs));
                                match (is_visible, is_non_exhaustive, is_uninhabited) {
                                    // Treat all uninhabited types in non-exhaustive variants as
                                    // `TyErr`.
                                    (_, true, true) => cx.tcx.types.err,
                                    // Treat all non-visible fields as `TyErr`. They can't appear
                                    // in any other pattern from this match (because they are
                                    // private), so their type does not matter - but we don't want
                                    // to know they are uninhabited.
                                    (false, ..) => cx.tcx.types.err,
                                    (true, ..) => {
                                        let ty = field.ty(cx.tcx, substs);
                                        match ty.kind {
                                            // If the field type returned is an array of an unknown
                                            // size return an TyErr.
                                            ty::Array(_, len)
                                                if len
                                                    .try_eval_usize(cx.tcx, cx.param_env)
                                                    .is_none() =>
                                            {
                                                cx.tcx.types.err
                                            }
                                            _ => ty,
                                        }
                                    }
                                }
                            })
                            .map(Pat::wildcard_from_ty)
                            .collect()
                    }
                }
                _ => vec![],
            },
            Slice(_) => match ty.kind {
                ty::Slice(ty) | ty::Array(ty, _) => {
                    let arity = self.arity(cx, ty);
                    (0..arity).map(|_| Pat::wildcard_from_ty(ty)).collect()
                }
                _ => bug!("bad slice pattern {:?} {:?}", self, ty),
            },
            ConstantValue(..) | FloatRange(..) | IntRange(..) | NonExhaustive => vec![],
        }
    }

    /// This computes the arity of a constructor. The arity of a constructor
    /// is how many subpattern patterns of that constructor should be expanded to.
    ///
    /// For instance, a tuple pattern `(_, 42, Some([]))` has the arity of 3.
    /// A struct pattern's arity is the number of fields it contains, etc.
    ///
    /// This must be consistent with `wildcard_subpatterns`, `specialize_one_pattern`, and `apply`.
    fn arity<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> u64 {
        debug!("Constructor::arity({:#?}, {:?})", self, ty);
        match self {
            Single | Variant(_) => match ty.kind {
                ty::Tuple(ref fs) => fs.len() as u64,
                ty::Slice(..) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
                ty::Ref(..) => 1,
                ty::Adt(adt, _) => {
                    adt.variants[self.variant_index_for_adt(cx, adt)].fields.len() as u64
                }
                _ => 0,
            },
            Slice(slice) => slice.arity(),
            ConstantValue(..) | FloatRange(..) | IntRange(..) | NonExhaustive => 0,
        }
    }

    /// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
    /// must have as many elements as this constructor's arity.
    ///
    /// This must be consistent with `wildcard_subpatterns`, `specialize_one_pattern`, and `arity`.
    ///
    /// Examples:
    /// `self`: `Constructor::Single`
    /// `ty`: `(u32, u32, u32)`
    /// `pats`: `[10, 20, _]`
    /// returns `(10, 20, _)`
    ///
    /// `self`: `Constructor::Variant(Option::Some)`
    /// `ty`: `Option<bool>`
    /// `pats`: `[false]`
    /// returns `Some(false)`
    fn apply<'a>(
        &self,
        cx: &MatchCheckCtxt<'a, 'tcx>,
        ty: Ty<'tcx>,
        pats: impl IntoIterator<Item = Pat<'tcx>>,
    ) -> Pat<'tcx> {
        let mut subpatterns = pats.into_iter();

        let pat = match self {
            Single | Variant(_) => match ty.kind {
                ty::Adt(..) | ty::Tuple(..) => {
                    let subpatterns = subpatterns
                        .enumerate()
                        .map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
                        .collect();

                    if let ty::Adt(adt, substs) = ty.kind {
                        if adt.is_enum() {
                            PatKind::Variant {
                                adt_def: adt,
                                substs,
                                variant_index: self.variant_index_for_adt(cx, adt),
                                subpatterns,
                            }
                        } else {
                            PatKind::Leaf { subpatterns }
                        }
                    } else {
                        PatKind::Leaf { subpatterns }
                    }
                }
                ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() },
                ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
                _ => PatKind::Wild,
            },
            Slice(slice) => match slice.pattern_kind() {
                FixedLen(_) => {
                    PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
                }
                VarLen(prefix, _) => {
                    let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
                    if slice.array_len.is_some() {
                        // Improves diagnostics a bit: if the type is a known-size array, instead
                        // of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
                        // This is incorrect if the size is not known, since `[_, ..]` captures
                        // arrays of lengths `>= 1` whereas `[..]` captures any length.
                        while !prefix.is_empty() && prefix.last().unwrap().is_wildcard() {
                            prefix.pop();
                        }
                    }
                    let suffix: Vec<_> = if slice.array_len.is_some() {
                        // Same as above.
                        subpatterns.skip_while(Pat::is_wildcard).collect()
                    } else {
                        subpatterns.collect()
                    };
                    let wild = Pat::wildcard_from_ty(ty);
                    PatKind::Slice { prefix, slice: Some(wild), suffix }
                }
            },
            &ConstantValue(value) => PatKind::Constant { value },
            &FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
            IntRange(range) => return range.to_pat(cx.tcx),
            NonExhaustive => PatKind::Wild,
        };

        Pat { ty, span: DUMMY_SP, kind: Box::new(pat) }
    }

    /// Like `apply`, but where all the subpatterns are wildcards `_`.
    fn apply_wildcards<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
        let subpatterns = self.wildcard_subpatterns(cx, ty).into_iter().rev();
        self.apply(cx, ty, subpatterns)
    }
}

#[derive(Clone, Debug)]
crate enum Usefulness<'tcx, 'p> {
    /// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns.
    Useful(Vec<&'p Pat<'tcx>>),
    /// Carries a list of witnesses of non-exhaustiveness.
    UsefulWithWitness(Vec<Witness<'tcx>>),
    NotUseful,
}

impl<'tcx, 'p> Usefulness<'tcx, 'p> {
    fn new_useful(preference: WitnessPreference) -> Self {
        match preference {
            ConstructWitness => UsefulWithWitness(vec![Witness(vec![])]),
            LeaveOutWitness => Useful(vec![]),
        }
    }

    fn is_useful(&self) -> bool {
        match *self {
            NotUseful => false,
            _ => true,
        }
    }

    fn apply_constructor(
        self,
        cx: &MatchCheckCtxt<'_, 'tcx>,
        ctor: &Constructor<'tcx>,
        ty: Ty<'tcx>,
    ) -> Self {
        match self {
            UsefulWithWitness(witnesses) => UsefulWithWitness(
                witnesses
                    .into_iter()
                    .map(|witness| witness.apply_constructor(cx, &ctor, ty))
                    .collect(),
            ),
            x => x,
        }
    }

    fn apply_wildcard(self, ty: Ty<'tcx>) -> Self {
        match self {
            UsefulWithWitness(witnesses) => {
                let wild = Pat::wildcard_from_ty(ty);
                UsefulWithWitness(
                    witnesses
                        .into_iter()
                        .map(|mut witness| {
                            witness.0.push(wild.clone());
                            witness
                        })
                        .collect(),
                )
            }
            x => x,
        }
    }

    fn apply_missing_ctors(
        self,
        cx: &MatchCheckCtxt<'_, 'tcx>,
        ty: Ty<'tcx>,
        missing_ctors: &MissingConstructors<'tcx>,
    ) -> Self {
        match self {
            UsefulWithWitness(witnesses) => {
                let new_patterns: Vec<_> =
                    missing_ctors.iter().map(|ctor| ctor.apply_wildcards(cx, ty)).collect();
                // Add the new patterns to each witness
                UsefulWithWitness(
                    witnesses
                        .into_iter()
                        .flat_map(|witness| {
                            new_patterns.iter().map(move |pat| {
                                let mut witness = witness.clone();
                                witness.0.push(pat.clone());
                                witness
                            })
                        })
                        .collect(),
                )
            }
            x => x,
        }
    }
}

#[derive(Copy, Clone, Debug)]
crate enum WitnessPreference {
    ConstructWitness,
    LeaveOutWitness,
}

#[derive(Copy, Clone, Debug)]
struct PatCtxt<'tcx> {
    ty: Ty<'tcx>,
    span: Span,
}

/// A witness of non-exhaustiveness for error reporting, represented
/// as a list of patterns (in reverse order of construction) with
/// wildcards inside to represent elements that can take any inhabitant
/// of the type as a value.
///
/// A witness against a list of patterns should have the same types
/// and length as the pattern matched against. Because Rust `match`
/// is always against a single pattern, at the end the witness will
/// have length 1, but in the middle of the algorithm, it can contain
/// multiple patterns.
///
/// For example, if we are constructing a witness for the match against
/// ```
/// struct Pair(Option<(u32, u32)>, bool);
///
/// match (p: Pair) {
///    Pair(None, _) => {}
///    Pair(_, false) => {}
/// }
/// ```
///
/// We'll perform the following steps:
/// 1. Start with an empty witness
///     `Witness(vec![])`
/// 2. Push a witness `Some(_)` against the `None`
///     `Witness(vec![Some(_)])`
/// 3. Push a witness `true` against the `false`
///     `Witness(vec![Some(_), true])`
/// 4. Apply the `Pair` constructor to the witnesses
///     `Witness(vec![Pair(Some(_), true)])`
///
/// The final `Pair(Some(_), true)` is then the resulting witness.
#[derive(Clone, Debug)]
crate struct Witness<'tcx>(Vec<Pat<'tcx>>);

impl<'tcx> Witness<'tcx> {
    crate fn single_pattern(self) -> Pat<'tcx> {
        assert_eq!(self.0.len(), 1);
        self.0.into_iter().next().unwrap()
    }

    /// Constructs a partial witness for a pattern given a list of
    /// patterns expanded by the specialization step.
    ///
    /// When a pattern P is discovered to be useful, this function is used bottom-up
    /// to reconstruct a complete witness, e.g., a pattern P' that covers a subset
    /// of values, V, where each value in that set is not covered by any previously
    /// used patterns and is covered by the pattern P'. Examples:
    ///
    /// left_ty: tuple of 3 elements
    /// pats: [10, 20, _]           => (10, 20, _)
    ///
    /// left_ty: struct X { a: (bool, &'static str), b: usize}
    /// pats: [(false, "foo"), 42]  => X { a: (false, "foo"), b: 42 }
    fn apply_constructor<'a>(
        mut self,
        cx: &MatchCheckCtxt<'a, 'tcx>,
        ctor: &Constructor<'tcx>,
        ty: Ty<'tcx>,
    ) -> Self {
        let arity = ctor.arity(cx, ty);
        let pat = {
            let len = self.0.len() as u64;
            let pats = self.0.drain((len - arity) as usize..).rev();
            ctor.apply(cx, ty, pats)
        };

        self.0.push(pat);

        self
    }
}

/// This determines the set of all possible constructors of a pattern matching
/// values of type `left_ty`. For vectors, this would normally be an infinite set
/// but is instead bounded by the maximum fixed length of slice patterns in
/// the column of patterns being analyzed.
///
/// We make sure to omit constructors that are statically impossible. E.g., for
/// `Option<!>`, we do not include `Some(_)` in the returned list of constructors.
/// Invariant: this returns an empty `Vec` if and only if the type is uninhabited (as determined by
/// `cx.is_uninhabited()`).
fn all_constructors<'a, 'tcx>(
    cx: &mut MatchCheckCtxt<'a, 'tcx>,
    pcx: PatCtxt<'tcx>,
) -> Vec<Constructor<'tcx>> {
    debug!("all_constructors({:?})", pcx.ty);
    let make_range = |start, end| {
        IntRange(
            // `unwrap()` is ok because we know the type is an integer.
            IntRange::from_range(cx.tcx, start, end, pcx.ty, &RangeEnd::Included, pcx.span)
                .unwrap(),
        )
    };
    match pcx.ty.kind {
        ty::Bool => {
            [true, false].iter().map(|&b| ConstantValue(ty::Const::from_bool(cx.tcx, b))).collect()
        }
        ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
            let len = len.eval_usize(cx.tcx, cx.param_env);
            if len != 0 && cx.is_uninhabited(sub_ty) {
                vec![]
            } else {
                vec![Slice(Slice { array_len: Some(len), kind: VarLen(0, 0) })]
            }
        }
        // Treat arrays of a constant but unknown length like slices.
        ty::Array(ref sub_ty, _) | ty::Slice(ref sub_ty) => {
            let kind = if cx.is_uninhabited(sub_ty) { FixedLen(0) } else { VarLen(0, 0) };
            vec![Slice(Slice { array_len: None, kind })]
        }
        ty::Adt(def, substs) if def.is_enum() => {
            let ctors: Vec<_> = if cx.tcx.features().exhaustive_patterns {
                // If `exhaustive_patterns` is enabled, we exclude variants known to be
                // uninhabited.
                def.variants
                    .iter()
                    .filter(|v| {
                        !v.uninhabited_from(cx.tcx, substs, def.adt_kind())
                            .contains(cx.tcx, cx.module)
                    })
                    .map(|v| Variant(v.def_id))
                    .collect()
            } else {
                def.variants.iter().map(|v| Variant(v.def_id)).collect()
            };

            // If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
            // additional "unknown" constructor.
            // There is no point in enumerating all possible variants, because the user can't
            // actually match against them all themselves. So we always return only the fictitious
            // constructor.
            // E.g., in an example like:
            // ```
            //     let err: io::ErrorKind = ...;
            //     match err {
            //         io::ErrorKind::NotFound => {},
            //     }
            // ```
            // we don't want to show every possible IO error, but instead have only `_` as the
            // witness.
            let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);

            // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
            // as though it had an "unknown" constructor to avoid exposing its emptyness. Note that
            // an empty match will still be considered exhaustive because that case is handled
            // separately in `check_match`.
            let is_secretly_empty =
                def.variants.is_empty() && !cx.tcx.features().exhaustive_patterns;

            if is_secretly_empty || is_declared_nonexhaustive { vec![NonExhaustive] } else { ctors }
        }
        ty::Char => {
            vec![
                // The valid Unicode Scalar Value ranges.
                make_range('\u{0000}' as u128, '\u{D7FF}' as u128),
                make_range('\u{E000}' as u128, '\u{10FFFF}' as u128),
            ]
        }
        ty::Int(_) | ty::Uint(_)
            if pcx.ty.is_ptr_sized_integral()
                && !cx.tcx.features().precise_pointer_size_matching =>
        {
            // `usize`/`isize` are not allowed to be matched exhaustively unless the
            // `precise_pointer_size_matching` feature is enabled. So we treat those types like
            // `#[non_exhaustive]` enums by returning a special unmatcheable constructor.
            vec![NonExhaustive]
        }
        ty::Int(ity) => {
            let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
            let min = 1u128 << (bits - 1);
            let max = min - 1;
            vec![make_range(min, max)]
        }
        ty::Uint(uty) => {
            let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size();
            let max = truncate(u128::max_value(), size);
            vec![make_range(0, max)]
        }
        _ => {
            if cx.is_uninhabited(pcx.ty) {
                vec![]
            } else {
                vec![Single]
            }
        }
    }
}

/// An inclusive interval, used for precise integer exhaustiveness checking.
/// `IntRange`s 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`.
#[derive(Clone, Debug)]
struct IntRange<'tcx> {
    range: RangeInclusive<u128>,
    ty: Ty<'tcx>,
    span: Span,
}

impl<'tcx> IntRange<'tcx> {
    #[inline]
    fn is_integral(ty: Ty<'_>) -> bool {
        match ty.kind {
            ty::Char | ty::Int(_) | ty::Uint(_) => true,
            _ => false,
        }
    }

    fn is_singleton(&self) -> bool {
        self.range.start() == self.range.end()
    }

    fn boundaries(&self) -> (u128, u128) {
        (*self.range.start(), *self.range.end())
    }

    /// Don't treat `usize`/`isize` exhaustively unless the `precise_pointer_size_matching` feature
    /// is enabled.
    fn treat_exhaustively(&self, tcx: TyCtxt<'tcx>) -> bool {
        !self.ty.is_ptr_sized_integral() || tcx.features().precise_pointer_size_matching
    }

    #[inline]
    fn integral_size_and_signed_bias(tcx: TyCtxt<'tcx>, ty: Ty<'_>) -> Option<(Size, u128)> {
        match ty.kind {
            ty::Char => Some((Size::from_bytes(4), 0)),
            ty::Int(ity) => {
                let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
                Some((size, 1u128 << (size.bits() as u128 - 1)))
            }
            ty::Uint(uty) => Some((Integer::from_attr(&tcx, UnsignedInt(uty)).size(), 0)),
            _ => None,
        }
    }

    #[inline]
    fn from_const(
        tcx: TyCtxt<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        value: &Const<'tcx>,
        span: Span,
    ) -> Option<IntRange<'tcx>> {
        if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, value.ty) {
            let ty = value.ty;
            let val = if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data, size })) =
                value.val
            {
                // For this specific pattern we can skip a lot of effort and go
                // straight to the result, after doing a bit of checking. (We
                // could remove this branch and just use the next branch, which
                // is more general but much slower.)
                Scalar::<()>::check_raw(data, size, target_size);
                data
            } else if let Some(val) = value.try_eval_bits(tcx, param_env, ty) {
                // This is a more general form of the previous branch.
                val
            } else {
                return None;
            };
            let val = val ^ bias;
            Some(IntRange { range: val..=val, ty, span })
        } else {
            None
        }
    }

    #[inline]
    fn from_range(
        tcx: TyCtxt<'tcx>,
        lo: u128,
        hi: u128,
        ty: Ty<'tcx>,
        end: &RangeEnd,
        span: Span,
    ) -> Option<IntRange<'tcx>> {
        if Self::is_integral(ty) {
            // Perform a shift if the underlying types are signed,
            // which makes the interval arithmetic simpler.
            let bias = IntRange::signed_bias(tcx, ty);
            let (lo, hi) = (lo ^ bias, hi ^ bias);
            let offset = (*end == RangeEnd::Excluded) as u128;
            if lo > hi || (lo == hi && *end == RangeEnd::Excluded) {
                // This should have been caught earlier by E0030.
                bug!("malformed range pattern: {}..={}", lo, (hi - offset));
            }
            Some(IntRange { range: lo..=(hi - offset), ty, span })
        } else {
            None
        }
    }

    fn from_pat(
        tcx: TyCtxt<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        pat: &Pat<'tcx>,
    ) -> Option<IntRange<'tcx>> {
        match pat_constructor(tcx, param_env, pat)? {
            IntRange(range) => Some(range),
            _ => None,
        }
    }

    // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
    fn signed_bias(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
        match ty.kind {
            ty::Int(ity) => {
                let bits = Integer::from_attr(&tcx, SignedInt(ity)).size().bits() as u128;
                1u128 << (bits - 1)
            }
            _ => 0,
        }
    }

    /// Returns a collection of ranges that spans the values covered by `ranges`, subtracted
    /// by the values covered by `self`: i.e., `ranges \ self` (in set notation).
    fn subtract_from(&self, ranges: Vec<IntRange<'tcx>>) -> Vec<IntRange<'tcx>> {
        let mut remaining_ranges = vec![];
        let ty = self.ty;
        let span = self.span;
        let (lo, hi) = self.boundaries();
        for subrange in ranges {
            let (subrange_lo, subrange_hi) = subrange.range.into_inner();
            if lo > subrange_hi || subrange_lo > hi {
                // The pattern doesn't intersect with the subrange at all,
                // so the subrange remains untouched.
                remaining_ranges.push(IntRange { range: subrange_lo..=subrange_hi, ty, span });
            } else {
                if lo > subrange_lo {
                    // The pattern intersects an upper section of the
                    // subrange, so a lower section will remain.
                    remaining_ranges.push(IntRange { range: subrange_lo..=(lo - 1), ty, span });
                }
                if hi < subrange_hi {
                    // The pattern intersects a lower section of the
                    // subrange, so an upper section will remain.
                    remaining_ranges.push(IntRange { range: (hi + 1)..=subrange_hi, ty, span });
                }
            }
        }
        remaining_ranges
    }

    fn is_subrange(&self, other: &Self) -> bool {
        other.range.start() <= self.range.start() && self.range.end() <= other.range.end()
    }

    fn intersection(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Option<Self> {
        let ty = self.ty;
        let (lo, hi) = self.boundaries();
        let (other_lo, other_hi) = other.boundaries();
        if self.treat_exhaustively(tcx) {
            if lo <= other_hi && other_lo <= hi {
                let span = other.span;
                Some(IntRange { range: max(lo, other_lo)..=min(hi, other_hi), ty, span })
            } else {
                None
            }
        } else {
            // If the range should not be treated exhaustively, fallback to checking for inclusion.
            if self.is_subrange(other) { Some(self.clone()) } else { None }
        }
    }

    fn suspicious_intersection(&self, other: &Self) -> bool {
        // `false` in the following cases:
        // 1     ----      // 1  ----------   // 1 ----        // 1       ----
        // 2  ----------   // 2     ----      // 2       ----  // 2 ----
        //
        // The following are currently `false`, but could be `true` in the future (#64007):
        // 1 ---------       // 1     ---------
        // 2     ----------  // 2 ----------
        //
        // `true` in the following cases:
        // 1 -------          // 1       -------
        // 2       --------   // 2 -------
        let (lo, hi) = self.boundaries();
        let (other_lo, other_hi) = other.boundaries();
        (lo == other_hi || hi == other_lo)
    }

    fn to_pat(&self, tcx: TyCtxt<'tcx>) -> Pat<'tcx> {
        let (lo, hi) = self.boundaries();

        let bias = IntRange::signed_bias(tcx, self.ty);
        let (lo, hi) = (lo ^ bias, hi ^ bias);

        let ty = ty::ParamEnv::empty().and(self.ty);
        let lo_const = ty::Const::from_bits(tcx, lo, ty);
        let hi_const = ty::Const::from_bits(tcx, hi, ty);

        let kind = if lo == hi {
            PatKind::Constant { value: lo_const }
        } else {
            PatKind::Range(PatRange { lo: lo_const, hi: hi_const, end: RangeEnd::Included })
        };

        // This is a brand new pattern, so we don't reuse `self.span`.
        Pat { ty: self.ty, span: DUMMY_SP, kind: Box::new(kind) }
    }
}

/// Ignore spans when comparing, they don't carry semantic information as they are only for lints.
impl<'tcx> std::cmp::PartialEq for IntRange<'tcx> {
    fn eq(&self, other: &Self) -> bool {
        self.range == other.range && self.ty == other.ty
    }
}

// A struct to compute a set of constructors equivalent to `all_ctors \ used_ctors`.
struct MissingConstructors<'tcx> {
    all_ctors: Vec<Constructor<'tcx>>,
    used_ctors: Vec<Constructor<'tcx>>,
}

impl<'tcx> MissingConstructors<'tcx> {
    fn new(all_ctors: Vec<Constructor<'tcx>>, used_ctors: Vec<Constructor<'tcx>>) -> Self {
        MissingConstructors { all_ctors, used_ctors }
    }

    fn into_inner(self) -> (Vec<Constructor<'tcx>>, Vec<Constructor<'tcx>>) {
        (self.all_ctors, self.used_ctors)
    }

    fn is_empty(&self) -> bool {
        self.iter().next().is_none()
    }
    /// Whether this contains all the constructors for the given type or only a
    /// subset.
    fn all_ctors_are_missing(&self) -> bool {
        self.used_ctors.is_empty()
    }

    /// Iterate over all_ctors \ used_ctors
    fn iter<'a>(&'a self) -> impl Iterator<Item = Constructor<'tcx>> + Captures<'a> {
        self.all_ctors.iter().flat_map(move |req_ctor| req_ctor.subtract_ctors(&self.used_ctors))
    }
}

impl<'tcx> fmt::Debug for MissingConstructors<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let ctors: Vec<_> = self.iter().collect();
        write!(f, "{:?}", ctors)
    }
}

/// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html.
/// The algorithm from the paper has been modified to correctly handle empty
/// types. The changes are:
///   (0) We don't exit early if the pattern matrix has zero rows. We just
///       continue to recurse over columns.
///   (1) all_constructors will only return constructors that are statically
///       possible. E.g., it will only return `Ok` for `Result<T, !>`.
///
/// This finds whether a (row) vector `v` of patterns is 'useful' in relation
/// to a set of such vectors `m` - this is defined as there being a set of
/// inputs that will match `v` but not any of the sets in `m`.
///
/// All the patterns at each column of the `matrix ++ v` matrix must
/// have the same type, except that wildcard (PatKind::Wild) patterns
/// with type `TyErr` are also allowed, even if the "type of the column"
/// is not `TyErr`. That is used to represent private fields, as using their
/// real type would assert that they are inhabited.
///
/// This is used both for reachability checking (if a pattern isn't useful in
/// relation to preceding patterns, it is not reachable) and exhaustiveness
/// checking (if a wildcard pattern is useful in relation to a matrix, the
/// matrix isn't exhaustive).
crate fn is_useful<'p, 'tcx>(
    cx: &mut MatchCheckCtxt<'p, 'tcx>,
    matrix: &Matrix<'p, 'tcx>,
    v: &PatStack<'p, 'tcx>,
    witness_preference: WitnessPreference,
    hir_id: HirId,
    is_top_level: bool,
) -> Usefulness<'tcx, 'p> {
    let &Matrix(ref rows) = matrix;
    debug!("is_useful({:#?}, {:#?})", matrix, v);

    // The base case. We are pattern-matching on () and the return value is
    // based on whether our matrix has a row or not.
    // NOTE: This could potentially be optimized by checking rows.is_empty()
    // first and then, if v is non-empty, the return value is based on whether
    // the type of the tuple we're checking is inhabited or not.
    if v.is_empty() {
        return if rows.is_empty() {
            Usefulness::new_useful(witness_preference)
        } else {
            NotUseful
        };
    };

    assert!(rows.iter().all(|r| r.len() == v.len()));

    // If the first pattern is an or-pattern, expand it.
    if let Some(vs) = v.expand_or_pat() {
        // We need to push the already-seen patterns into the matrix in order to detect redundant
        // branches like `Some(_) | Some(0)`. We also keep track of the unreachable subpatterns.
        let mut matrix = matrix.clone();
        let mut unreachable_pats = Vec::new();
        let mut any_is_useful = false;
        for v in vs {
            let res = is_useful(cx, &matrix, &v, witness_preference, hir_id, false);
            match res {
                Useful(pats) => {
                    any_is_useful = true;
                    unreachable_pats.extend(pats);
                }
                NotUseful => unreachable_pats.push(v.head()),
                UsefulWithWitness(_) => {
                    bug!("Encountered or-pat in `v` during exhaustiveness checking")
                }
            }
            matrix.push(v);
        }
        return if any_is_useful { Useful(unreachable_pats) } else { NotUseful };
    }

    let (ty, span) = matrix
        .heads()
        .map(|r| (r.ty, r.span))
        .find(|(ty, _)| !ty.references_error())
        .unwrap_or((v.head().ty, v.head().span));
    let pcx = PatCtxt {
        // TyErr is used to represent the type of wildcard patterns matching
        // against inaccessible (private) fields of structs, so that we won't
        // be able to observe whether the types of the struct's fields are
        // inhabited.
        //
        // If the field is truly inaccessible, then all the patterns
        // matching against it must be wildcard patterns, so its type
        // does not matter.
        //
        // However, if we are matching against non-wildcard patterns, we
        // need to know the real type of the field so we can specialize
        // against it. This primarily occurs through constants - they
        // can include contents for fields that are inaccessible at the
        // location of the match. In that case, the field's type is
        // inhabited - by the constant - so we can just use it.
        //
        // FIXME: this might lead to "unstable" behavior with macro hygiene
        // introducing uninhabited patterns for inaccessible fields. We
        // need to figure out how to model that.
        ty,
        span,
    };

    debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v.head());

    if let Some(constructor) = pat_constructor(cx.tcx, cx.param_env, v.head()) {
        debug!("is_useful - expanding constructor: {:#?}", constructor);
        split_grouped_constructors(
            cx.tcx,
            cx.param_env,
            pcx,
            vec![constructor],
            matrix,
            pcx.span,
            Some(hir_id),
        )
        .into_iter()
        .map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id))
        .find(|result| result.is_useful())
        .unwrap_or(NotUseful)
    } else {
        debug!("is_useful - expanding wildcard");

        let used_ctors: Vec<Constructor<'_>> =
            matrix.heads().filter_map(|p| pat_constructor(cx.tcx, cx.param_env, p)).collect();
        debug!("used_ctors = {:#?}", used_ctors);
        // `all_ctors` are all the constructors for the given type, which
        // should all be represented (or caught with the wild pattern `_`).
        let all_ctors = all_constructors(cx, pcx);
        debug!("all_ctors = {:#?}", all_ctors);

        // `missing_ctors` is the set of constructors from the same type as the
        // first column of `matrix` that are matched only by wildcard patterns
        // from the first column.
        //
        // Therefore, if there is some pattern that is unmatched by `matrix`,
        // it will still be unmatched if the first constructor is replaced by
        // any of the constructors in `missing_ctors`

        // Missing constructors are those that are not matched by any non-wildcard patterns in the
        // current column. We only fully construct them on-demand, because they're rarely used and
        // can be big.
        let missing_ctors = MissingConstructors::new(all_ctors, used_ctors);

        debug!("missing_ctors.empty()={:#?}", missing_ctors.is_empty(),);

        if missing_ctors.is_empty() {
            let (all_ctors, _) = missing_ctors.into_inner();
            split_grouped_constructors(cx.tcx, cx.param_env, pcx, all_ctors, matrix, DUMMY_SP, None)
                .into_iter()
                .map(|c| {
                    is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id)
                })
                .find(|result| result.is_useful())
                .unwrap_or(NotUseful)
        } else {
            let matrix = matrix.specialize_wildcard();
            let v = v.to_tail();
            let usefulness = is_useful(cx, &matrix, &v, witness_preference, hir_id, false);

            // In this case, there's at least one "free"
            // constructor that is only matched against by
            // wildcard patterns.
            //
            // There are 2 ways we can report a witness here.
            // Commonly, we can report all the "free"
            // constructors as witnesses, e.g., if we have:
            //
            // ```
            //     enum Direction { N, S, E, W }
            //     let Direction::N = ...;
            // ```
            //
            // we can report 3 witnesses: `S`, `E`, and `W`.
            //
            // However, there is a case where we don't want
            // to do this and instead report a single `_` witness:
            // if the user didn't actually specify a constructor
            // in this arm, e.g., in
            // ```
            //     let x: (Direction, Direction, bool) = ...;
            //     let (_, _, false) = x;
            // ```
            // we don't want to show all 16 possible witnesses
            // `(<direction-1>, <direction-2>, true)` - we are
            // satisfied with `(_, _, true)`. In this case,
            // `used_ctors` is empty.
            // The exception is: if we are at the top-level, for example in an empty match, we
            // sometimes prefer reporting the list of constructors instead of just `_`.
            let report_ctors_rather_than_wildcard = is_top_level && !IntRange::is_integral(pcx.ty);
            if missing_ctors.all_ctors_are_missing() && !report_ctors_rather_than_wildcard {
                // All constructors are unused. Add a wild pattern
                // rather than each individual constructor.
                usefulness.apply_wildcard(pcx.ty)
            } else {
                // Construct for each missing constructor a "wild" version of this
                // constructor, that matches everything that can be built with
                // it. For example, if `ctor` is a `Constructor::Variant` for
                // `Option::Some`, we get the pattern `Some(_)`.
                usefulness.apply_missing_ctors(cx, pcx.ty, &missing_ctors)
            }
        }
    }
}

/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e., `is_useful` applied
/// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
fn is_useful_specialized<'p, 'tcx>(
    cx: &mut MatchCheckCtxt<'p, 'tcx>,
    matrix: &Matrix<'p, 'tcx>,
    v: &PatStack<'p, 'tcx>,
    ctor: Constructor<'tcx>,
    lty: Ty<'tcx>,
    witness_preference: WitnessPreference,
    hir_id: HirId,
) -> Usefulness<'tcx, 'p> {
    debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty);

    let ctor_wild_subpatterns =
        cx.pattern_arena.alloc_from_iter(ctor.wildcard_subpatterns(cx, lty));
    let matrix = matrix.specialize_constructor(cx, &ctor, ctor_wild_subpatterns);
    v.specialize_constructor(cx, &ctor, ctor_wild_subpatterns)
        .map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, false))
        .map(|u| u.apply_constructor(cx, &ctor, lty))
        .unwrap_or(NotUseful)
}

/// Determines the constructor that the given pattern can be specialized to.
/// Returns `None` in case of a catch-all, which can't be specialized.
fn pat_constructor<'tcx>(
    tcx: TyCtxt<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    pat: &Pat<'tcx>,
) -> Option<Constructor<'tcx>> {
    match *pat.kind {
        PatKind::AscribeUserType { .. } => bug!(), // Handled by `expand_pattern`
        PatKind::Binding { .. } | PatKind::Wild => None,
        PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(Single),
        PatKind::Variant { adt_def, variant_index, .. } => {
            Some(Variant(adt_def.variants[variant_index].def_id))
        }
        PatKind::Constant { value } => {
            if let Some(int_range) = IntRange::from_const(tcx, param_env, value, pat.span) {
                Some(IntRange(int_range))
            } else {
                match (value.val, &value.ty.kind) {
                    (_, ty::Array(_, n)) => {
                        let len = n.eval_usize(tcx, param_env);
                        Some(Slice(Slice { array_len: Some(len), kind: FixedLen(len) }))
                    }
                    (ty::ConstKind::Value(ConstValue::Slice { start, end, .. }), ty::Slice(_)) => {
                        let len = (end - start) as u64;
                        Some(Slice(Slice { array_len: None, kind: FixedLen(len) }))
                    }
                    // FIXME(oli-obk): implement `deref` for `ConstValue`
                    // (ty::ConstKind::Value(ConstValue::ByRef { .. }), ty::Slice(_)) => { ... }
                    _ => Some(ConstantValue(value)),
                }
            }
        }
        PatKind::Range(PatRange { lo, hi, end }) => {
            let ty = lo.ty;
            if let Some(int_range) = IntRange::from_range(
                tcx,
                lo.eval_bits(tcx, param_env, lo.ty),
                hi.eval_bits(tcx, param_env, hi.ty),
                ty,
                &end,
                pat.span,
            ) {
                Some(IntRange(int_range))
            } else {
                Some(FloatRange(lo, hi, end))
            }
        }
        PatKind::Array { ref prefix, ref slice, ref suffix }
        | PatKind::Slice { ref prefix, ref slice, ref suffix } => {
            let array_len = match pat.ty.kind {
                ty::Array(_, length) => Some(length.eval_usize(tcx, param_env)),
                ty::Slice(_) => None,
                _ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty),
            };
            let prefix = prefix.len() as u64;
            let suffix = suffix.len() as u64;
            let kind =
                if slice.is_some() { VarLen(prefix, suffix) } else { FixedLen(prefix + suffix) };
            Some(Slice(Slice { array_len, kind }))
        }
        PatKind::Or { .. } => bug!("Or-pattern should have been expanded earlier on."),
    }
}

// checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
// meaning all other types will compare unequal and thus equal patterns often do not cause the
// second pattern to lint about unreachable match arms.
fn slice_pat_covered_by_const<'tcx>(
    tcx: TyCtxt<'tcx>,
    _span: Span,
    const_val: &'tcx ty::Const<'tcx>,
    prefix: &[Pat<'tcx>],
    slice: &Option<Pat<'tcx>>,
    suffix: &[Pat<'tcx>],
    param_env: ty::ParamEnv<'tcx>,
) -> Result<bool, ErrorReported> {
    let const_val_val = if let ty::ConstKind::Value(val) = const_val.val {
        val
    } else {
        bug!(
            "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}",
            const_val,
            prefix,
            slice,
            suffix,
        )
    };

    let data: &[u8] = match (const_val_val, &const_val.ty.kind) {
        (ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => {
            assert_eq!(*t, tcx.types.u8);
            let n = n.eval_usize(tcx, param_env);
            let ptr = Pointer::new(AllocId(0), offset);
            alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
        }
        (ConstValue::Slice { data, start, end }, ty::Slice(t)) => {
            assert_eq!(*t, tcx.types.u8);
            let ptr = Pointer::new(AllocId(0), Size::from_bytes(start as u64));
            data.get_bytes(&tcx, ptr, Size::from_bytes((end - start) as u64)).unwrap()
        }
        // FIXME(oli-obk): create a way to extract fat pointers from ByRef
        (_, ty::Slice(_)) => return Ok(false),
        _ => bug!(
            "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}",
            const_val,
            prefix,
            slice,
            suffix,
        ),
    };

    let pat_len = prefix.len() + suffix.len();
    if data.len() < pat_len || (slice.is_none() && data.len() > pat_len) {
        return Ok(false);
    }

    for (ch, pat) in data[..prefix.len()]
        .iter()
        .zip(prefix)
        .chain(data[data.len() - suffix.len()..].iter().zip(suffix))
    {
        match pat.kind {
            box PatKind::Constant { value } => {
                let b = value.eval_bits(tcx, param_env, pat.ty);
                assert_eq!(b as u8 as u128, b);
                if b as u8 != *ch {
                    return Ok(false);
                }
            }
            _ => {}
        }
    }

    Ok(true)
}

/// 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 `is_useful_specialized` 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.)
///
/// `hir_id` is `None` when we're evaluating the wildcard pattern, do not lint for overlapping in
/// ranges that case.
///
/// This also splits variable-length slices into fixed-length slices.
fn split_grouped_constructors<'p, 'tcx>(
    tcx: TyCtxt<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    pcx: PatCtxt<'tcx>,
    ctors: Vec<Constructor<'tcx>>,
    matrix: &Matrix<'p, 'tcx>,
    span: Span,
    hir_id: Option<HirId>,
) -> Vec<Constructor<'tcx>> {
    let ty = pcx.ty;
    let mut split_ctors = Vec::with_capacity(ctors.len());
    debug!("split_grouped_constructors({:#?}, {:#?})", matrix, ctors);

    for ctor in ctors.into_iter() {
        match ctor {
            IntRange(ctor_range) if ctor_range.treat_exhaustively(tcx) => {
                // Fast-track if the range is trivial. In particular, don't do the overlapping
                // ranges check.
                if ctor_range.is_singleton() {
                    split_ctors.push(IntRange(ctor_range));
                    continue;
                }

                /// Represents a border between 2 integers. Because the intervals spanning borders
                /// must be able to cover every integer, we need to be able to represent
                /// 2^128 + 1 such borders.
                #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
                enum Border {
                    JustBefore(u128),
                    AfterMax,
                }

                // A function for extracting the borders of an integer interval.
                fn range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
                    let (lo, hi) = r.range.into_inner();
                    let from = Border::JustBefore(lo);
                    let to = match hi.checked_add(1) {
                        Some(m) => Border::JustBefore(m),
                        None => Border::AfterMax,
                    };
                    vec![from, to].into_iter()
                }

                // Collect the span and range of all the intersecting ranges to lint on likely
                // incorrect range patterns. (#63987)
                let mut overlaps = vec![];
                // `borders` is the set of borders between equivalence classes: each equivalence
                // class lies between 2 borders.
                let row_borders = matrix
                    .0
                    .iter()
                    .flat_map(|row| {
                        IntRange::from_pat(tcx, param_env, row.head()).map(|r| (r, row.len()))
                    })
                    .flat_map(|(range, row_len)| {
                        let intersection = ctor_range.intersection(tcx, &range);
                        let should_lint = ctor_range.suspicious_intersection(&range);
                        if let (Some(range), 1, true) = (&intersection, row_len, should_lint) {
                            // FIXME: for now, only check for overlapping ranges on simple range
                            // patterns. Otherwise with the current logic the following is detected
                            // as overlapping:
                            //   match (10u8, true) {
                            //    (0 ..= 125, false) => {}
                            //    (126 ..= 255, false) => {}
                            //    (0 ..= 255, true) => {}
                            //  }
                            overlaps.push(range.clone());
                        }
                        intersection
                    })
                    .flat_map(|range| range_borders(range));
                let ctor_borders = range_borders(ctor_range.clone());
                let mut borders: Vec<_> = row_borders.chain(ctor_borders).collect();
                borders.sort_unstable();

                lint_overlapping_patterns(tcx, hir_id, ctor_range, ty, overlaps);

                // We're going to iterate through every adjacent pair of borders, making sure that
                // each represents an interval of nonnegative length, and convert each such
                // interval into a constructor.
                split_ctors.extend(
                    borders
                        .windows(2)
                        .filter_map(|window| match (window[0], window[1]) {
                            (Border::JustBefore(n), Border::JustBefore(m)) => {
                                if n < m {
                                    Some(IntRange { range: n..=(m - 1), ty, span })
                                } else {
                                    None
                                }
                            }
                            (Border::JustBefore(n), Border::AfterMax) => {
                                Some(IntRange { range: n..=u128::MAX, ty, span })
                            }
                            (Border::AfterMax, _) => None,
                        })
                        .map(IntRange),
                );
            }
            Slice(Slice { array_len, kind: VarLen(self_prefix, self_suffix) }) => {
                // The exhaustiveness-checking paper does not include any details on
                // checking variable-length slice patterns. However, they are 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 from one
                // of the sufficiently-large lengths can be transformed to an
                // equally-valid witness from any other length, so we only have
                // to check slice lengths from the "minimal sufficiently-large length"
                // and below.
                //
                // 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 - for
                // but the slice from 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.

                let mut max_prefix_len = self_prefix;
                let mut max_suffix_len = self_suffix;
                let mut max_fixed_len = 0;

                let head_ctors =
                    matrix.heads().filter_map(|pat| pat_constructor(tcx, param_env, pat));
                for ctor in head_ctors {
                    match ctor {
                        Slice(slice) => match slice.pattern_kind() {
                            FixedLen(len) => {
                                max_fixed_len = cmp::max(max_fixed_len, len);
                            }
                            VarLen(prefix, suffix) => {
                                max_prefix_len = cmp::max(max_prefix_len, prefix);
                                max_suffix_len = cmp::max(max_suffix_len, suffix);
                            }
                        },
                        _ => {}
                    }
                }

                // For diagnostics, we keep the prefix and suffix lengths separate, so in the case
                // where `max_fixed_len + 1` is the largest, we adapt `max_prefix_len` accordingly,
                // so that `L = max_prefix_len + max_suffix_len`.
                if max_fixed_len + 1 >= max_prefix_len + max_suffix_len {
                    // The subtraction can't overflow thanks to the above check.
                    // The new `max_prefix_len` is also guaranteed to be larger than its previous
                    // value.
                    max_prefix_len = max_fixed_len + 1 - max_suffix_len;
                }

                match array_len {
                    Some(len) => {
                        let kind = if max_prefix_len + max_suffix_len < len {
                            VarLen(max_prefix_len, max_suffix_len)
                        } else {
                            FixedLen(len)
                        };
                        split_ctors.push(Slice(Slice { array_len, kind }));
                    }
                    None => {
                        // `ctor` originally covered the range `(self_prefix +
                        // self_suffix..infinity)`. We now split it into two: lengths smaller than
                        // `max_prefix_len + max_suffix_len` are treated independently as
                        // fixed-lengths slices, and lengths above are captured by a final VarLen
                        // constructor.
                        split_ctors.extend(
                            (self_prefix + self_suffix..max_prefix_len + max_suffix_len)
                                .map(|len| Slice(Slice { array_len, kind: FixedLen(len) })),
                        );
                        split_ctors.push(Slice(Slice {
                            array_len,
                            kind: VarLen(max_prefix_len, max_suffix_len),
                        }));
                    }
                }
            }
            // Any other constructor can be used unchanged.
            _ => split_ctors.push(ctor),
        }
    }

    debug!("split_grouped_constructors(..)={:#?}", split_ctors);
    split_ctors
}

fn lint_overlapping_patterns<'tcx>(
    tcx: TyCtxt<'tcx>,
    hir_id: Option<HirId>,
    ctor_range: IntRange<'tcx>,
    ty: Ty<'tcx>,
    overlaps: Vec<IntRange<'tcx>>,
) {
    if let (true, Some(hir_id)) = (!overlaps.is_empty(), hir_id) {
        let mut err = tcx.struct_span_lint_hir(
            lint::builtin::OVERLAPPING_PATTERNS,
            hir_id,
            ctor_range.span,
            "multiple patterns covering the same range",
        );
        err.span_label(ctor_range.span, "overlapping patterns");
        for int_range in overlaps {
            // Use the real type for user display of the ranges:
            err.span_label(
                int_range.span,
                &format!(
                    "this range overlaps on `{}`",
                    IntRange { range: int_range.range, ty, span: DUMMY_SP }.to_pat(tcx),
                ),
            );
        }
        err.emit();
    }
}

fn constructor_covered_by_range<'tcx>(
    tcx: TyCtxt<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    ctor: &Constructor<'tcx>,
    pat: &Pat<'tcx>,
) -> Option<()> {
    if let Single = ctor {
        return Some(());
    }

    let (pat_from, pat_to, pat_end, ty) = match *pat.kind {
        PatKind::Constant { value } => (value, value, RangeEnd::Included, value.ty),
        PatKind::Range(PatRange { lo, hi, end }) => (lo, hi, end, lo.ty),
        _ => bug!("`constructor_covered_by_range` called with {:?}", pat),
    };
    let (ctor_from, ctor_to, ctor_end) = match *ctor {
        ConstantValue(value) => (value, value, RangeEnd::Included),
        FloatRange(from, to, ctor_end) => (from, to, ctor_end),
        _ => bug!("`constructor_covered_by_range` called with {:?}", ctor),
    };
    trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, pat_from, pat_to, ty);

    let to = compare_const_vals(tcx, ctor_to, pat_to, param_env, ty)?;
    let from = compare_const_vals(tcx, ctor_from, pat_from, param_env, ty)?;
    let intersects = (from == Ordering::Greater || from == Ordering::Equal)
        && (to == Ordering::Less || (pat_end == ctor_end && to == Ordering::Equal));
    if intersects { Some(()) } else { None }
}

fn patterns_for_variant<'p, 'tcx>(
    cx: &mut MatchCheckCtxt<'p, 'tcx>,
    subpatterns: &'p [FieldPat<'tcx>],
    ctor_wild_subpatterns: &'p [Pat<'tcx>],
    is_non_exhaustive: bool,
) -> PatStack<'p, 'tcx> {
    let mut result: SmallVec<_> = ctor_wild_subpatterns.iter().collect();

    for subpat in subpatterns {
        if !is_non_exhaustive || !cx.is_uninhabited(subpat.pattern.ty) {
            result[subpat.field.index()] = &subpat.pattern;
        }
    }

    debug!(
        "patterns_for_variant({:#?}, {:#?}) = {:#?}",
        subpatterns, ctor_wild_subpatterns, result
    );
    PatStack::from_vec(result)
}

/// This is the main specialization step. It expands the pattern
/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
/// Returns `None` if the pattern does not have the given constructor.
///
/// OTOH, slice patterns with a subslice pattern (tail @ ..) can be expanded into multiple
/// different patterns.
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
/// fields filled with wild patterns.
fn specialize_one_pattern<'p, 'tcx>(
    cx: &mut MatchCheckCtxt<'p, 'tcx>,
    pat: &'p Pat<'tcx>,
    constructor: &Constructor<'tcx>,
    ctor_wild_subpatterns: &'p [Pat<'tcx>],
) -> Option<PatStack<'p, 'tcx>> {
    if let NonExhaustive = constructor {
        // Only a wildcard pattern can match the special extra constructor
        return if pat.is_wildcard() { Some(PatStack::default()) } else { None };
    }

    let result = match *pat.kind {
        PatKind::AscribeUserType { .. } => bug!(), // Handled by `expand_pattern`

        PatKind::Binding { .. } | PatKind::Wild => Some(ctor_wild_subpatterns.iter().collect()),

        PatKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
            let ref variant = adt_def.variants[variant_index];
            let is_non_exhaustive = cx.is_foreign_non_exhaustive_variant(pat.ty, variant);
            Some(Variant(variant.def_id))
                .filter(|variant_constructor| variant_constructor == constructor)
                .map(|_| {
                    patterns_for_variant(cx, subpatterns, ctor_wild_subpatterns, is_non_exhaustive)
                })
        }

        PatKind::Leaf { ref subpatterns } => {
            Some(patterns_for_variant(cx, subpatterns, ctor_wild_subpatterns, false))
        }

        PatKind::Deref { ref subpattern } => Some(PatStack::from_pattern(subpattern)),

        PatKind::Constant { value } if constructor.is_slice() => {
            // We extract an `Option` for the pointer because slices of zero
            // elements don't necessarily point to memory, they are usually
            // just integers. The only time they should be pointing to memory
            // is when they are subslices of nonzero slices.
            let (alloc, offset, n, ty) = match value.ty.kind {
                ty::Array(t, n) => {
                    let n = n.eval_usize(cx.tcx, cx.param_env);
                    // Shortcut for `n == 0` where no matter what `alloc` and `offset` we produce,
                    // the result would be exactly what we early return here.
                    if n == 0 {
                        if ctor_wild_subpatterns.len() as u64 == 0 {
                            return Some(PatStack::from_slice(&[]));
                        } else {
                            return None;
                        }
                    }
                    match value.val {
                        ty::ConstKind::Value(ConstValue::ByRef { offset, alloc, .. }) => {
                            (Cow::Borrowed(alloc), offset, n, t)
                        }
                        _ => span_bug!(pat.span, "array pattern is {:?}", value,),
                    }
                }
                ty::Slice(t) => {
                    match value.val {
                        ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => {
                            let offset = Size::from_bytes(start as u64);
                            let n = (end - start) as u64;
                            (Cow::Borrowed(data), offset, n, t)
                        }
                        ty::ConstKind::Value(ConstValue::ByRef { .. }) => {
                            // FIXME(oli-obk): implement `deref` for `ConstValue`
                            return None;
                        }
                        _ => span_bug!(
                            pat.span,
                            "slice pattern constant must be scalar pair but is {:?}",
                            value,
                        ),
                    }
                }
                _ => span_bug!(
                    pat.span,
                    "unexpected const-val {:?} with ctor {:?}",
                    value,
                    constructor,
                ),
            };
            if ctor_wild_subpatterns.len() as u64 == n {
                // convert a constant slice/array pattern to a list of patterns.
                let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
                let ptr = Pointer::new(AllocId(0), offset);
                (0..n)
                    .map(|i| {
                        let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
                        let scalar = alloc.read_scalar(&cx.tcx, ptr, layout.size).ok()?;
                        let scalar = scalar.not_undef().ok()?;
                        let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
                        let pattern =
                            Pat { ty, span: pat.span, kind: box PatKind::Constant { value } };
                        Some(&*cx.pattern_arena.alloc(pattern))
                    })
                    .collect()
            } else {
                None
            }
        }

        PatKind::Constant { .. } | PatKind::Range { .. } => {
            // If the constructor is a:
            // - Single value: add a row if the pattern contains the constructor.
            // - Range: add a row if the constructor intersects the pattern.
            if let IntRange(ctor) = constructor {
                match IntRange::from_pat(cx.tcx, cx.param_env, pat) {
                    Some(pat) => ctor.intersection(cx.tcx, &pat).map(|_| {
                        // Constructor splitting should ensure that all intersections we encounter
                        // are actually inclusions.
                        assert!(ctor.is_subrange(&pat));
                        PatStack::default()
                    }),
                    _ => None,
                }
            } else {
                // Fallback for non-ranges and ranges that involve
                // floating-point numbers, which are not conveniently handled
                // by `IntRange`. For these cases, the constructor may not be a
                // range so intersection actually devolves into being covered
                // by the pattern.
                constructor_covered_by_range(cx.tcx, cx.param_env, constructor, pat)
                    .map(|()| PatStack::default())
            }
        }

        PatKind::Array { ref prefix, ref slice, ref suffix }
        | PatKind::Slice { ref prefix, ref slice, ref suffix } => match *constructor {
            Slice(_) => {
                let pat_len = prefix.len() + suffix.len();
                if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
                    if slice_count == 0 || slice.is_some() {
                        Some(
                            prefix
                                .iter()
                                .chain(
                                    ctor_wild_subpatterns
                                        .iter()
                                        .skip(prefix.len())
                                        .take(slice_count)
                                        .chain(suffix.iter()),
                                )
                                .collect(),
                        )
                    } else {
                        None
                    }
                } else {
                    None
                }
            }
            ConstantValue(cv) => {
                match slice_pat_covered_by_const(
                    cx.tcx,
                    pat.span,
                    cv,
                    prefix,
                    slice,
                    suffix,
                    cx.param_env,
                ) {
                    Ok(true) => Some(PatStack::default()),
                    Ok(false) => None,
                    Err(ErrorReported) => None,
                }
            }
            _ => span_bug!(pat.span, "unexpected ctor {:?} for slice pat", constructor),
        },

        PatKind::Or { .. } => bug!("Or-pattern should have been expanded earlier on."),
    };
    debug!("specialize({:#?}, {:#?}) = {:#?}", pat, ctor_wild_subpatterns, result);

    result
}
