1 //! Note: tests specific to this file can be found in:
3 //! - `ui/pattern/usefulness`
5 //! - `ui/consts/const_in_pattern`
6 //! - `ui/rfc-2008-non-exhaustive`
7 //! - `ui/half-open-range-patterns`
8 //! - probably many others
10 //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
11 //! reason not to, for example if they depend on a particular feature like `or_patterns`.
15 //! This file includes the logic for exhaustiveness and usefulness checking for
16 //! pattern-matching. Specifically, given a list of patterns for a type, we can
18 //! (a) the patterns cover every possible constructor for the type (exhaustiveness)
19 //! (b) each pattern is necessary (usefulness)
21 //! The algorithm implemented here is a modified version of the one described in
22 //! [this paper](http://moscova.inria.fr/~maranget/papers/warn/index.html).
23 //! However, to save future implementors from reading the original paper, we
24 //! summarise the algorithm here to hopefully save time and be a little clearer
25 //! (without being so rigorous).
29 //! The core of the algorithm revolves about a "usefulness" check. In particular, we
30 //! are trying to compute a predicate `U(P, p)` where `P` is a list of patterns (we refer to this as
31 //! a matrix). `U(P, p)` represents whether, given an existing list of patterns
32 //! `P_1 ..= P_m`, adding a new pattern `p` will be "useful" (that is, cover previously-
33 //! uncovered values of the type).
35 //! If we have this predicate, then we can easily compute both exhaustiveness of an
36 //! entire set of patterns and the individual usefulness of each one.
37 //! (a) the set of patterns is exhaustive iff `U(P, _)` is false (i.e., adding a wildcard
38 //! match doesn't increase the number of values we're matching)
39 //! (b) a pattern `P_i` is not useful if `U(P[0..=(i-1), P_i)` is false (i.e., adding a
40 //! pattern to those that have come before it doesn't increase the number of values
45 //! The idea that powers everything that is done in this file is the following: a value is made
46 //! from a constructor applied to some fields. Examples of constructors are `Some`, `None`, `(,)`
47 //! (the 2-tuple constructor), `Foo {..}` (the constructor for a struct `Foo`), and `2` (the
48 //! constructor for the number `2`). Fields are just a (possibly empty) list of values.
50 //! Some of the constructors listed above might feel weird: `None` and `2` don't take any
51 //! arguments. This is part of what makes constructors so general: we will consider plain values
52 //! like numbers and string literals to be constructors that take no arguments, also called "0-ary
53 //! constructors"; they are the simplest case of constructors. This allows us to see any value as
54 //! made up from a tree of constructors, each having a given number of children. For example:
55 //! `(None, Ok(0))` is made from 4 different constructors.
57 //! This idea can be extended to patterns: a pattern captures a set of possible values, and we can
58 //! describe this set using constructors. For example, `Err(_)` captures all values of the type
59 //! `Result<T, E>` that start with the `Err` constructor (for some choice of `T` and `E`). The
60 //! wildcard `_` captures all values of the given type starting with any of the constructors for
63 //! We use this to compute whether different patterns might capture a same value. Do the patterns
64 //! `Ok("foo")` and `Err(_)` capture a common value? The answer is no, because the first pattern
65 //! captures only values starting with the `Ok` constructor and the second only values starting
66 //! with the `Err` constructor. Do the patterns `Some(42)` and `Some(1..10)` intersect? They might,
67 //! since they both capture values starting with `Some`. To be certain, we need to dig under the
68 //! `Some` constructor and continue asking the question. This is the main idea behind the
69 //! exhaustiveness algorithm: by looking at patterns constructor-by-constructor, we can efficiently
70 //! figure out if some new pattern might capture a value that hadn't been captured by previous
73 //! Constructors are represented by the `Constructor` enum, and its fields by the `Fields` enum.
74 //! Most of the complexity of this file resides in transforming between patterns and
75 //! (`Constructor`, `Fields`) pairs, handling all the special cases correctly.
77 //! Caveat: this constructors/fields distinction doesn't quite cover every Rust value. For example
78 //! a value of type `Rc<u64>` doesn't fit this idea very well, nor do various other things.
79 //! However, this idea covers most of the cases that are relevant to exhaustiveness checking.
84 //! Recall that `U(P, p)` represents whether, given an existing list of patterns (aka matrix) `P`,
85 //! adding a new pattern `p` will cover previously-uncovered values of the type.
86 //! During the course of the algorithm, the rows of the matrix won't just be individual patterns,
87 //! but rather partially-deconstructed patterns in the form of a list of fields. The paper
88 //! calls those pattern-vectors, and we will call them pattern-stacks. The same holds for the
91 //! For example, say we have the following:
94 //! // x: (Option<bool>, Result<()>)
96 //! (Some(true), _) => {}
97 //! (None, Err(())) => {}
98 //! (None, Err(_)) => {}
102 //! Here, the matrix `P` starts as:
106 //! [(Some(true), _)],
107 //! [(None, Err(()))],
108 //! [(None, Err(_))],
112 //! We can tell it's not exhaustive, because `U(P, _)` is true (we're not covering
113 //! `[(Some(false), _)]`, for instance). In addition, row 3 is not useful, because
114 //! all the values it covers are already covered by row 2.
116 //! A list of patterns can be thought of as a stack, because we are mainly interested in the top of
117 //! the stack at any given point, and we can pop or apply constructors to get new pattern-stacks.
118 //! To match the paper, the top of the stack is at the beginning / on the left.
120 //! There are two important operations on pattern-stacks necessary to understand the algorithm:
122 //! 1. We can pop a given constructor off the top of a stack. This operation is called
123 //! `specialize`, and is denoted `S(c, p)` where `c` is a constructor (like `Some` or
124 //! `None`) and `p` a pattern-stack.
125 //! If the pattern on top of the stack can cover `c`, this removes the constructor and
126 //! pushes its arguments onto the stack. It also expands OR-patterns into distinct patterns.
127 //! Otherwise the pattern-stack is discarded.
128 //! This essentially filters those pattern-stacks whose top covers the constructor `c` and
129 //! discards the others.
131 //! For example, the first pattern above initially gives a stack `[(Some(true), _)]`. If we
132 //! pop the tuple constructor, we are left with `[Some(true), _]`, and if we then pop the
133 //! `Some` constructor we get `[true, _]`. If we had popped `None` instead, we would get
136 //! This returns zero or more new pattern-stacks, as follows. We look at the pattern `p_1`
137 //! on top of the stack, and we have four cases:
139 //! 1.1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We
140 //! push onto the stack the arguments of this constructor, and return the result:
141 //! `r_1, .., r_a, p_2, .., p_n`
143 //! 1.2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and
146 //! 1.3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c` has
147 //! arguments (its arity), and return the resulting stack:
148 //! `_, .., _, p_2, .., p_n`
150 //! 1.4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
152 //! - `S(c, (r_1, p_2, .., p_n))`
153 //! - `S(c, (r_2, p_2, .., p_n))`
155 //! 2. We can pop a wildcard off the top of the stack. This is called `S(_, p)`, where `p` is
156 //! a pattern-stack. Note: the paper calls this `D(p)`.
157 //! This is used when we know there are missing constructor cases, but there might be
158 //! existing wildcard patterns, so to check the usefulness of the matrix, we have to check
159 //! all its *other* components.
161 //! It is computed as follows. We look at the pattern `p_1` on top of the stack,
162 //! and we have three cases:
163 //! 2.1. `p_1 = c(r_1, .., r_a)`. We discard the current stack and return nothing.
164 //! 2.2. `p_1 = _`. We return the rest of the stack:
166 //! 2.3. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
168 //! - `S(_, (r_1, p_2, .., p_n))`
169 //! - `S(_, (r_2, p_2, .., p_n))`
171 //! Note that the OR-patterns are not always used directly in Rust, but are used to derive the
172 //! exhaustive integer matching rules, so they're written here for posterity.
174 //! Both those operations extend straightforwardly to a list or pattern-stacks, i.e. a matrix, by
175 //! working row-by-row. Popping a constructor ends up keeping only the matrix rows that start with
176 //! the given constructor, and popping a wildcard keeps those rows that start with a wildcard.
179 //! The algorithm for computing `U`
180 //! -------------------------------
181 //! The algorithm is inductive (on the number of columns: i.e., components of tuple patterns).
182 //! That means we're going to check the components from left-to-right, so the algorithm
183 //! operates principally on the first component of the matrix and new pattern-stack `p`.
184 //! This algorithm is realised in the `is_useful` function.
186 //! Base case. (`n = 0`, i.e., an empty tuple pattern)
187 //! - If `P` already contains an empty pattern (i.e., if the number of patterns `m > 0`),
188 //! then `U(P, p)` is false.
189 //! - Otherwise, `P` must be empty, so `U(P, p)` is true.
191 //! Inductive step. (`n > 0`, i.e., whether there's at least one column
192 //! [which may then be expanded into further columns later])
193 //! We're going to match on the top of the new pattern-stack, `p_1`.
194 //! - If `p_1 == c(r_1, .., r_a)`, i.e. we have a constructor pattern.
195 //! Then, the usefulness of `p_1` can be reduced to whether it is useful when
196 //! we ignore all the patterns in the first column of `P` that involve other constructors.
197 //! This is where `S(c, P)` comes in:
198 //! `U(P, p) := U(S(c, P), S(c, p))`
200 //! For example, if `P` is:
209 //! and `p` is `[Some(false), 0]`, then we don't care about row 2 since we know `p` only
210 //! matches values that row 2 doesn't. For row 1 however, we need to dig into the
211 //! arguments of `Some` to know whether some new value is covered. So we compute
212 //! `U([[true, _]], [false, 0])`.
214 //! - If `p_1 == _`, then we look at the list of constructors that appear in the first
215 //! component of the rows of `P`:
216 //! + If there are some constructors that aren't present, then we might think that the
217 //! wildcard `_` is useful, since it covers those constructors that weren't covered
219 //! That's almost correct, but only works if there were no wildcards in those first
220 //! components. So we need to check that `p` is useful with respect to the rows that
221 //! start with a wildcard, if there are any. This is where `S(_, x)` comes in:
222 //! `U(P, p) := U(S(_, P), S(_, p))`
224 //! For example, if `P` is:
229 //! [None, false, 1],
233 //! and `p` is `[_, false, _]`, the `Some` constructor doesn't appear in `P`. So if we
234 //! only had row 2, we'd know that `p` is useful. However row 1 starts with a
235 //! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
237 //! + Otherwise, all possible constructors (for the relevant type) are present. In this
238 //! case we must check whether the wildcard pattern covers any unmatched value. For
239 //! that, we can think of the `_` pattern as a big OR-pattern that covers all
240 //! possible constructors. For `Option`, that would mean `_ = None | Some(_)` for
241 //! example. The wildcard pattern is useful in this case if it is useful when
242 //! specialized to one of the possible constructors. So we compute:
243 //! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
245 //! For example, if `P` is:
254 //! and `p` is `[_, false]`, both `None` and `Some` constructors appear in the first
255 //! components of `P`. We will therefore try popping both constructors in turn: we
256 //! compute `U([[true, _]], [_, false])` for the `Some` constructor, and `U([[false]],
257 //! [false])` for the `None` constructor. The first case returns true, so we know that
258 //! `p` is useful for `P`. Indeed, it matches `[Some(false), _]` that wasn't matched
261 //! - If `p_1 == r_1 | r_2`, then the usefulness depends on each `r_i` separately:
262 //! `U(P, p) := U(P, (r_1, p_2, .., p_n))
263 //! || U(P, (r_2, p_2, .., p_n))`
265 //! Modifications to the algorithm
266 //! ------------------------------
267 //! The algorithm in the paper doesn't cover some of the special cases that arise in Rust, for
268 //! example uninhabited types and variable-length slice patterns. These are drawn attention to
269 //! throughout the code below. I'll make a quick note here about how exhaustive integer matching is
270 //! accounted for, though.
272 //! Exhaustive integer matching
273 //! ---------------------------
274 //! An integer type can be thought of as a (huge) sum type: 1 | 2 | 3 | ...
275 //! So to support exhaustive integer matching, we can make use of the logic in the paper for
276 //! OR-patterns. However, we obviously can't just treat ranges x..=y as individual sums, because
277 //! they are likely gigantic. So we instead treat ranges as constructors of the integers. This means
278 //! that we have a constructor *of* constructors (the integers themselves). We then need to work
279 //! through all the inductive step rules above, deriving how the ranges would be treated as
280 //! OR-patterns, and making sure that they're treated in the same way even when they're ranges.
281 //! There are really only four special cases here:
282 //! - When we match on a constructor that's actually a range, we have to treat it as if we would
284 //! + It turns out that we can simply extend the case for single-value patterns in
285 //! `specialize` to either be *equal* to a value constructor, or *contained within* a range
287 //! + When the pattern itself is a range, you just want to tell whether any of the values in
288 //! the pattern range coincide with values in the constructor range, which is precisely
290 //! Since when encountering a range pattern for a value constructor, we also use inclusion, it
291 //! means that whenever the constructor is a value/range and the pattern is also a value/range,
292 //! we can simply use intersection to test usefulness.
293 //! - When we're testing for usefulness of a pattern and the pattern's first component is a
295 //! + If all the constructors appear in the matrix, we have a slight complication. By default,
296 //! the behaviour (i.e., a disjunction over specialised matrices for each constructor) is
297 //! invalid, because we want a disjunction over every *integer* in each range, not just a
298 //! disjunction over every range. This is a bit more tricky to deal with: essentially we need
299 //! to form equivalence classes of subranges of the constructor range for which the behaviour
300 //! of the matrix `P` and new pattern `p` are the same. This is described in more
301 //! detail in `Constructor::split`.
302 //! + If some constructors are missing from the matrix, it turns out we don't need to do
303 //! anything special (because we know none of the integers are actually wildcards: i.e., we
304 //! can't span wildcards using ranges).
306 use self::Usefulness::*;
307 use self::WitnessPreference::*;
309 use super::deconstruct_pat::{Constructor, Fields, SplitWildcard};
310 use super::{Pat, PatKind};
311 use super::{PatternFoldable, PatternFolder};
313 use rustc_data_structures::captures::Captures;
314 use rustc_data_structures::sync::OnceCell;
316 use rustc_arena::TypedArena;
317 use rustc_hir::def_id::DefId;
318 use rustc_hir::HirId;
319 use rustc_middle::ty::{self, Ty, TyCtxt};
320 use rustc_span::Span;
322 use smallvec::{smallvec, SmallVec};
324 use std::iter::{FromIterator, IntoIterator};
326 crate struct MatchCheckCtxt<'a, 'tcx> {
327 crate tcx: TyCtxt<'tcx>,
328 /// The module in which the match occurs. This is necessary for
329 /// checking inhabited-ness of types because whether a type is (visibly)
330 /// inhabited can depend on whether it was defined in the current module or
331 /// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty
332 /// outside its module and should not be matchable with an empty match statement.
334 crate param_env: ty::ParamEnv<'tcx>,
335 crate pattern_arena: &'a TypedArena<Pat<'tcx>>,
338 impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
339 pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
340 if self.tcx.features().exhaustive_patterns {
341 self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
347 /// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
348 pub(super) fn is_foreign_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
350 ty::Adt(def, ..) => {
351 def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did.is_local()
358 #[derive(Copy, Clone)]
359 pub(super) struct PatCtxt<'a, 'p, 'tcx> {
360 pub(super) cx: &'a MatchCheckCtxt<'p, 'tcx>,
361 /// Current state of the matrix.
362 pub(super) matrix: &'a Matrix<'p, 'tcx>,
363 /// Type of the current column under investigation.
364 pub(super) ty: Ty<'tcx>,
365 /// Span of the current pattern under investigation.
366 pub(super) span: Span,
367 /// Whether the current pattern is the whole pattern as found in a match arm, or if it's a
369 pub(super) is_top_level: bool,
372 crate fn expand_pattern<'tcx>(pat: Pat<'tcx>) -> Pat<'tcx> {
373 LiteralExpander.fold_pattern(&pat)
376 struct LiteralExpander;
378 impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
379 fn fold_pattern(&mut self, pat: &Pat<'tcx>) -> Pat<'tcx> {
380 debug!("fold_pattern {:?} {:?} {:?}", pat, pat.ty.kind(), pat.kind);
381 match (pat.ty.kind(), pat.kind.as_ref()) {
382 (_, PatKind::Binding { subpattern: Some(s), .. }) => s.fold_with(self),
383 (_, PatKind::AscribeUserType { subpattern: s, .. }) => s.fold_with(self),
384 (ty::Ref(_, t, _), PatKind::Constant { .. }) if t.is_str() => {
385 // Treat string literal patterns as deref patterns to a `str` constant, i.e.
386 // `&CONST`. This expands them like other const patterns. This could have been done
387 // in `const_to_pat`, but that causes issues with the rest of the matching code.
388 let mut new_pat = pat.super_fold_with(self);
389 // Make a fake const pattern of type `str` (instead of `&str`). That the carried
390 // constant value still knows it is of type `&str`.
393 kind: Box::new(PatKind::Deref { subpattern: new_pat }),
398 _ => pat.super_fold_with(self),
403 impl<'tcx> Pat<'tcx> {
404 pub(super) fn is_wildcard(&self) -> bool {
405 matches!(*self.kind, PatKind::Binding { subpattern: None, .. } | PatKind::Wild)
409 /// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
411 #[derive(Debug, Clone)]
412 struct PatStack<'p, 'tcx> {
413 pats: SmallVec<[&'p Pat<'tcx>; 2]>,
414 /// Cache for the constructor of the head
415 head_ctor: OnceCell<Constructor<'tcx>>,
418 impl<'p, 'tcx> PatStack<'p, 'tcx> {
419 fn from_pattern(pat: &'p Pat<'tcx>) -> Self {
420 Self::from_vec(smallvec![pat])
423 fn from_vec(vec: SmallVec<[&'p Pat<'tcx>; 2]>) -> Self {
424 PatStack { pats: vec, head_ctor: OnceCell::new() }
427 fn is_empty(&self) -> bool {
431 fn len(&self) -> usize {
435 fn head(&self) -> &'p Pat<'tcx> {
439 fn head_ctor<'a>(&'a self, cx: &MatchCheckCtxt<'p, 'tcx>) -> &'a Constructor<'tcx> {
440 self.head_ctor.get_or_init(|| Constructor::from_pat(cx, self.head()))
443 fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> {
444 self.pats.iter().copied()
447 // If the first pattern is an or-pattern, expand this pattern. Otherwise, return `None`.
448 fn expand_or_pat(&self) -> Option<Vec<Self>> {
451 } else if let PatKind::Or { pats } = &*self.head().kind {
455 let mut new_patstack = PatStack::from_pattern(pat);
456 new_patstack.pats.extend_from_slice(&self.pats[1..]);
466 /// This computes `S(self.head_ctor(), self)`. See top of the file for explanations.
468 /// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
469 /// fields filled with wild patterns.
471 /// This is roughly the inverse of `Constructor::apply`.
472 fn pop_head_constructor(&self, ctor_wild_subpatterns: &Fields<'p, 'tcx>) -> PatStack<'p, 'tcx> {
473 // We pop the head pattern and push the new fields extracted from the arguments of
476 ctor_wild_subpatterns.replace_with_pattern_arguments(self.head()).filtered_patterns();
477 new_fields.extend_from_slice(&self.pats[1..]);
478 PatStack::from_vec(new_fields)
482 impl<'p, 'tcx> Default for PatStack<'p, 'tcx> {
483 fn default() -> Self {
484 Self::from_vec(smallvec![])
488 impl<'p, 'tcx> PartialEq for PatStack<'p, 'tcx> {
489 fn eq(&self, other: &Self) -> bool {
490 self.pats == other.pats
494 impl<'p, 'tcx> FromIterator<&'p Pat<'tcx>> for PatStack<'p, 'tcx> {
495 fn from_iter<T>(iter: T) -> Self
497 T: IntoIterator<Item = &'p Pat<'tcx>>,
499 Self::from_vec(iter.into_iter().collect())
504 #[derive(Clone, PartialEq)]
505 pub(super) struct Matrix<'p, 'tcx> {
506 patterns: Vec<PatStack<'p, 'tcx>>,
509 impl<'p, 'tcx> Matrix<'p, 'tcx> {
511 Matrix { patterns: vec![] }
514 /// Number of columns of this matrix. `None` is the matrix is empty.
515 pub(super) fn column_count(&self) -> Option<usize> {
516 self.patterns.get(0).map(|r| r.len())
519 /// Pushes a new row to the matrix. If the row starts with an or-pattern, this expands it.
520 fn push(&mut self, row: PatStack<'p, 'tcx>) {
521 if let Some(rows) = row.expand_or_pat() {
523 // We recursively expand the or-patterns of the new rows.
524 // This is necessary as we might have `0 | (1 | 2)` or e.g., `x @ 0 | x @ (1 | 2)`.
528 self.patterns.push(row);
532 /// Iterate over the first component of each row
533 fn heads<'a>(&'a self) -> impl Iterator<Item = &'a Pat<'tcx>> + Captures<'p> {
534 self.patterns.iter().map(|r| r.head())
537 /// Iterate over the first constructor of each row.
538 pub(super) fn head_ctors<'a>(
540 cx: &'a MatchCheckCtxt<'p, 'tcx>,
541 ) -> impl Iterator<Item = &'a Constructor<'tcx>> + Captures<'p> {
542 self.patterns.iter().map(move |r| r.head_ctor(cx))
545 /// Iterate over the first constructor and the corresponding span of each row.
546 pub(super) fn head_ctors_and_spans<'a>(
548 cx: &'a MatchCheckCtxt<'p, 'tcx>,
549 ) -> impl Iterator<Item = (&'a Constructor<'tcx>, Span)> + Captures<'p> {
550 self.patterns.iter().map(move |r| (r.head_ctor(cx), r.head().span))
553 /// This computes `S(constructor, self)`. See top of the file for explanations.
554 fn specialize_constructor(
556 pcx: PatCtxt<'_, 'p, 'tcx>,
557 ctor: &Constructor<'tcx>,
558 ctor_wild_subpatterns: &Fields<'p, 'tcx>,
559 ) -> Matrix<'p, 'tcx> {
562 .filter(|r| ctor.is_covered_by(pcx, r.head_ctor(pcx.cx)))
563 .map(|r| r.pop_head_constructor(ctor_wild_subpatterns))
568 /// Pretty-printer for matrices of patterns, example:
571 /// +++++++++++++++++++++++++++++
573 /// +++++++++++++++++++++++++++++
574 /// + true + [First] +
575 /// +++++++++++++++++++++++++++++
576 /// + true + [Second(true)] +
577 /// +++++++++++++++++++++++++++++
579 /// +++++++++++++++++++++++++++++
580 /// + _ + [_, _, tail @ ..] +
581 /// +++++++++++++++++++++++++++++
583 impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
584 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 let Matrix { patterns: m, .. } = self;
588 let pretty_printed_matrix: Vec<Vec<String>> =
589 m.iter().map(|row| row.iter().map(|pat| format!("{:?}", pat)).collect()).collect();
591 let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0);
592 assert!(m.iter().all(|row| row.len() == column_count));
593 let column_widths: Vec<usize> = (0..column_count)
594 .map(|col| pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0))
597 let total_width = column_widths.iter().cloned().sum::<usize>() + column_count * 3 + 1;
598 let br = "+".repeat(total_width);
599 write!(f, "{}\n", br)?;
600 for row in pretty_printed_matrix {
602 for (column, pat_str) in row.into_iter().enumerate() {
604 write!(f, "{:1$}", pat_str, column_widths[column])?;
608 write!(f, "{}\n", br)?;
614 impl<'p, 'tcx> FromIterator<PatStack<'p, 'tcx>> for Matrix<'p, 'tcx> {
615 fn from_iter<T>(iter: T) -> Self
617 T: IntoIterator<Item = PatStack<'p, 'tcx>>,
619 let mut matrix = Matrix::empty();
621 // Using `push` ensures we correctly expand or-patterns.
628 /// Represents a set of `Span`s closed under the containment relation. That is, if a `Span` is
629 /// contained in the set then all `Span`s contained in it are also implicitly contained in the set.
630 /// In particular this means that when intersecting two sets, taking the intersection of some span
631 /// and one of its subspans returns the subspan, whereas a simple `HashSet` would have returned an
632 /// empty intersection.
633 /// It is assumed that two spans don't overlap without one being contained in the other; in other
634 /// words, that the inclusion structure forms a tree and not a DAG.
635 /// Intersection is not very efficient. It compares everything pairwise. If needed it could be made
636 /// faster by sorting the `Span`s and merging cleverly.
637 #[derive(Debug, Clone, Default)]
638 pub(crate) struct SpanSet {
639 /// The minimal set of `Span`s required to represent the whole set. If A and B are `Span`s in
640 /// the `SpanSet`, and A is a descendant of B, then only B will be in `root_spans`.
641 /// Invariant: the spans are disjoint.
642 root_spans: Vec<Span>,
646 /// Creates an empty set.
651 /// Tests whether the set is empty.
652 pub(crate) fn is_empty(&self) -> bool {
653 self.root_spans.is_empty()
656 /// Iterate over the disjoint list of spans at the roots of this set.
657 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = Span> + Captures<'a> {
658 self.root_spans.iter().copied()
661 /// Tests whether the set contains a given Span.
662 fn contains(&self, span: Span) -> bool {
663 self.iter().any(|root_span| root_span.contains(span))
666 /// Add a span to the set if we know the span has no intersection in this set.
667 fn push_nonintersecting(&mut self, new_span: Span) {
668 self.root_spans.push(new_span);
671 fn intersection_mut(&mut self, other: &Self) {
672 if self.is_empty() || other.is_empty() {
676 // Those that were in `self` but not contained in `other`
677 let mut leftover = SpanSet::new();
678 // We keep the elements in `self` that are also in `other`.
679 self.root_spans.retain(|span| {
680 let retain = other.contains(*span);
682 leftover.root_spans.push(*span);
686 // We keep the elements in `other` that are also in the original `self`. You might think
687 // this is not needed because `self` already contains the intersection. But those aren't
688 // just sets of things. If `self = [a]`, `other = [b]` and `a` contains `b`, then `b`
689 // belongs in the intersection but we didn't catch it in the filtering above. We look at
690 // `leftover` instead of the full original `self` to avoid duplicates.
691 for span in other.iter() {
692 if leftover.contains(span) {
693 self.root_spans.push(span);
699 #[derive(Clone, Debug)]
700 crate enum Usefulness<'tcx> {
701 /// Pontentially carries a set of sub-branches that have been found to be unreachable. Used
702 /// only in the presence of or-patterns, otherwise it stays empty.
704 /// Carries a list of witnesses of non-exhaustiveness.
705 UsefulWithWitness(Vec<Witness<'tcx>>),
709 impl<'tcx> Usefulness<'tcx> {
710 fn new_useful(preference: WitnessPreference) -> Self {
712 ConstructWitness => UsefulWithWitness(vec![Witness(vec![])]),
713 LeaveOutWitness => Useful(Default::default()),
717 /// When trying several branches and each returns a `Usefulness`, we need to combine the
718 /// results together.
719 fn merge(usefulnesses: impl Iterator<Item = Self>) -> Self {
720 // If we have detected some unreachable sub-branches, we only want to keep them when they
721 // were unreachable in _all_ branches. Eg. in the following, the last `true` is unreachable
722 // in the second branch of the first or-pattern, but not otherwise. Therefore we don't want
723 // to lint that it is unreachable.
725 // match (true, true) {
726 // (true, true) => {}
727 // (false | true, false | true) => {}
730 // Here however we _do_ want to lint that the last `false` is unreachable. So we don't want
731 // to intersect the spans that come directly from the or-pattern, since each branch of the
732 // or-pattern brings a new disjoint pattern.
736 // None | Some(true | false) => {}
740 // Is `None` when no branch was useful. Will often be `Some(Spanset::new())` because the
741 // sets are only non-empty in the presence of or-patterns.
742 let mut unreachables: Option<SpanSet> = None;
743 // Witnesses of usefulness, if any.
744 let mut witnesses = Vec::new();
746 for u in usefulnesses {
748 Useful(spans) if spans.is_empty() => {
749 // Once we reach the empty set, more intersections won't change the result.
750 return Useful(SpanSet::new());
753 if let Some(unreachables) = &mut unreachables {
754 if !unreachables.is_empty() {
755 unreachables.intersection_mut(&spans);
757 if unreachables.is_empty() {
758 return Useful(SpanSet::new());
761 unreachables = Some(spans);
765 UsefulWithWitness(wits) => {
766 witnesses.extend(wits);
771 if !witnesses.is_empty() {
772 UsefulWithWitness(witnesses)
773 } else if let Some(unreachables) = unreachables {
780 /// After calculating the usefulness for a branch of an or-pattern, call this to make this
781 /// usefulness mergeable with those from the other branches.
782 fn unsplit_or_pat(self, this_span: Span, or_pat_spans: &[Span]) -> Self {
784 Useful(mut spans) => {
785 // We register the spans of the other branches of this or-pattern as being
786 // unreachable from this one. This ensures that intersecting together the sets of
787 // spans returns what we want.
788 // Until we optimize `SpanSet` however, intersecting this entails a number of
789 // comparisons quadratic in the number of branches.
790 for &span in or_pat_spans {
791 if span != this_span {
792 spans.push_nonintersecting(span);
801 /// After calculating usefulness after a specialization, call this to recontruct a usefulness
802 /// that makes sense for the matrix pre-specialization. This new usefulness can then be merged
803 /// with the results of specializing with the other constructors.
804 fn apply_constructor<'p>(
806 pcx: PatCtxt<'_, 'p, 'tcx>,
807 ctor: &Constructor<'tcx>,
808 ctor_wild_subpatterns: &Fields<'p, 'tcx>,
811 UsefulWithWitness(witnesses) => {
812 let new_witnesses = if ctor.is_wildcard() {
813 let mut split_wildcard = SplitWildcard::new(pcx);
814 split_wildcard.split(pcx);
815 let new_patterns = split_wildcard.report_missing_patterns(pcx);
818 .flat_map(|witness| {
819 new_patterns.iter().map(move |pat| {
820 let mut witness = witness.clone();
821 witness.0.push(pat.clone());
829 .map(|witness| witness.apply_constructor(pcx, &ctor, ctor_wild_subpatterns))
832 UsefulWithWitness(new_witnesses)
839 #[derive(Copy, Clone, Debug)]
840 enum WitnessPreference {
845 /// A witness of non-exhaustiveness for error reporting, represented
846 /// as a list of patterns (in reverse order of construction) with
847 /// wildcards inside to represent elements that can take any inhabitant
848 /// of the type as a value.
850 /// A witness against a list of patterns should have the same types
851 /// and length as the pattern matched against. Because Rust `match`
852 /// is always against a single pattern, at the end the witness will
853 /// have length 1, but in the middle of the algorithm, it can contain
854 /// multiple patterns.
856 /// For example, if we are constructing a witness for the match against
859 /// struct Pair(Option<(u32, u32)>, bool);
861 /// match (p: Pair) {
862 /// Pair(None, _) => {}
863 /// Pair(_, false) => {}
867 /// We'll perform the following steps:
868 /// 1. Start with an empty witness
869 /// `Witness(vec![])`
870 /// 2. Push a witness `Some(_)` against the `None`
871 /// `Witness(vec![Some(_)])`
872 /// 3. Push a witness `true` against the `false`
873 /// `Witness(vec![Some(_), true])`
874 /// 4. Apply the `Pair` constructor to the witnesses
875 /// `Witness(vec![Pair(Some(_), true)])`
877 /// The final `Pair(Some(_), true)` is then the resulting witness.
878 #[derive(Clone, Debug)]
879 crate struct Witness<'tcx>(Vec<Pat<'tcx>>);
881 impl<'tcx> Witness<'tcx> {
882 /// Asserts that the witness contains a single pattern, and returns it.
883 fn single_pattern(self) -> Pat<'tcx> {
884 assert_eq!(self.0.len(), 1);
885 self.0.into_iter().next().unwrap()
888 /// Constructs a partial witness for a pattern given a list of
889 /// patterns expanded by the specialization step.
891 /// When a pattern P is discovered to be useful, this function is used bottom-up
892 /// to reconstruct a complete witness, e.g., a pattern P' that covers a subset
893 /// of values, V, where each value in that set is not covered by any previously
894 /// used patterns and is covered by the pattern P'. Examples:
896 /// left_ty: tuple of 3 elements
897 /// pats: [10, 20, _] => (10, 20, _)
899 /// left_ty: struct X { a: (bool, &'static str), b: usize}
900 /// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
901 fn apply_constructor<'p>(
903 pcx: PatCtxt<'_, 'p, 'tcx>,
904 ctor: &Constructor<'tcx>,
905 ctor_wild_subpatterns: &Fields<'p, 'tcx>,
908 let len = self.0.len();
909 let arity = ctor_wild_subpatterns.len();
910 let pats = self.0.drain((len - arity)..).rev();
911 ctor_wild_subpatterns.replace_fields(pcx.cx, pats).apply(pcx, ctor)
920 /// Algorithm from <http://moscova.inria.fr/~maranget/papers/warn/index.html>.
921 /// The algorithm from the paper has been modified to correctly handle empty
922 /// types. The changes are:
923 /// (0) We don't exit early if the pattern matrix has zero rows. We just
924 /// continue to recurse over columns.
925 /// (1) all_constructors will only return constructors that are statically
926 /// possible. E.g., it will only return `Ok` for `Result<T, !>`.
928 /// This finds whether a (row) vector `v` of patterns is 'useful' in relation
929 /// to a set of such vectors `m` - this is defined as there being a set of
930 /// inputs that will match `v` but not any of the sets in `m`.
932 /// All the patterns at each column of the `matrix ++ v` matrix must have the same type.
934 /// This is used both for reachability checking (if a pattern isn't useful in
935 /// relation to preceding patterns, it is not reachable) and exhaustiveness
936 /// checking (if a wildcard pattern is useful in relation to a matrix, the
937 /// matrix isn't exhaustive).
939 /// `is_under_guard` is used to inform if the pattern has a guard. If it
940 /// has one it must not be inserted into the matrix. This shouldn't be
941 /// relied on for soundness.
942 fn is_useful<'p, 'tcx>(
943 cx: &MatchCheckCtxt<'p, 'tcx>,
944 matrix: &Matrix<'p, 'tcx>,
945 v: &PatStack<'p, 'tcx>,
946 witness_preference: WitnessPreference,
948 is_under_guard: bool,
950 ) -> Usefulness<'tcx> {
951 let Matrix { patterns: rows, .. } = matrix;
952 debug!("is_useful({:#?}, {:#?})", matrix, v);
954 // The base case. We are pattern-matching on () and the return value is
955 // based on whether our matrix has a row or not.
956 // NOTE: This could potentially be optimized by checking rows.is_empty()
957 // first and then, if v is non-empty, the return value is based on whether
958 // the type of the tuple we're checking is inhabited or not.
960 return if rows.is_empty() {
961 Usefulness::new_useful(witness_preference)
967 assert!(rows.iter().all(|r| r.len() == v.len()));
969 // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
970 let ty = matrix.heads().next().map(|r| r.ty).unwrap_or(v.head().ty);
971 let pcx = PatCtxt { cx, matrix, ty, span: v.head().span, is_top_level };
973 debug!("is_useful_expand_first_col: ty={:#?}, expanding {:#?}", pcx.ty, v.head());
975 // If the first pattern is an or-pattern, expand it.
976 let ret = if let Some(vs) = v.expand_or_pat() {
977 let subspans: Vec<_> = vs.iter().map(|v| v.head().span).collect();
978 // We expand the or pattern, trying each of its branches in turn and keeping careful track
979 // of possible unreachable sub-branches.
980 let mut matrix = matrix.clone();
981 let usefulnesses = vs.into_iter().map(|v| {
982 let v_span = v.head().span;
984 is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
985 // If pattern has a guard don't add it to the matrix.
987 // We push the already-seen patterns into the matrix in order to detect redundant
988 // branches like `Some(_) | Some(0)`.
991 usefulness.unsplit_or_pat(v_span, &subspans)
993 Usefulness::merge(usefulnesses)
995 let v_ctor = v.head_ctor(cx);
996 if let Constructor::IntRange(ctor_range) = &v_ctor {
997 // Lint on likely incorrect range patterns (#63987)
998 ctor_range.lint_overlapping_range_endpoints(pcx, hir_id)
1000 // We split the head constructor of `v`.
1001 let split_ctors = v_ctor.split(pcx);
1002 // For each constructor, we compute whether there's a value that starts with it that would
1003 // witness the usefulness of `v`.
1004 let usefulnesses = split_ctors.into_iter().map(|ctor| {
1005 // We cache the result of `Fields::wildcards` because it is used a lot.
1006 let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor);
1007 let matrix = pcx.matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
1008 let v = v.pop_head_constructor(&ctor_wild_subpatterns);
1010 is_useful(pcx.cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
1011 usefulness.apply_constructor(pcx, &ctor, &ctor_wild_subpatterns)
1013 Usefulness::merge(usefulnesses)
1015 debug!("is_useful::returns({:#?}, {:#?}) = {:?}", matrix, v, ret);
1019 /// The arm of a match expression.
1020 #[derive(Clone, Copy)]
1021 crate struct MatchArm<'p, 'tcx> {
1022 /// The pattern must have been lowered through `MatchVisitor::lower_pattern`.
1023 crate pat: &'p super::Pat<'tcx>,
1024 crate hir_id: HirId,
1025 crate has_guard: bool,
1028 /// The output of checking a match for exhaustiveness and arm reachability.
1029 crate struct UsefulnessReport<'p, 'tcx> {
1030 /// For each arm of the input, whether that arm is reachable after the arms above it.
1031 crate arm_usefulness: Vec<(MatchArm<'p, 'tcx>, Usefulness<'tcx>)>,
1032 /// If the match is exhaustive, this is empty. If not, this contains witnesses for the lack of
1034 crate non_exhaustiveness_witnesses: Vec<super::Pat<'tcx>>,
1037 /// The entrypoint for the usefulness algorithm. Computes whether a match is exhaustive and which
1038 /// of its arms are reachable.
1040 /// Note: the input patterns must have been lowered through `MatchVisitor::lower_pattern`.
1041 crate fn compute_match_usefulness<'p, 'tcx>(
1042 cx: &MatchCheckCtxt<'p, 'tcx>,
1043 arms: &[MatchArm<'p, 'tcx>],
1044 scrut_hir_id: HirId,
1046 ) -> UsefulnessReport<'p, 'tcx> {
1047 let mut matrix = Matrix::empty();
1048 let arm_usefulness: Vec<_> = arms
1052 let v = PatStack::from_pattern(arm.pat);
1054 is_useful(cx, &matrix, &v, LeaveOutWitness, arm.hir_id, arm.has_guard, true);
1062 let wild_pattern = cx.pattern_arena.alloc(super::Pat::wildcard_from_ty(scrut_ty));
1063 let v = PatStack::from_pattern(wild_pattern);
1064 let usefulness = is_useful(cx, &matrix, &v, ConstructWitness, scrut_hir_id, false, true);
1065 let non_exhaustiveness_witnesses = match usefulness {
1066 NotUseful => vec![], // Wildcard pattern isn't useful, so the match is exhaustive.
1067 UsefulWithWitness(pats) => {
1068 if pats.is_empty() {
1069 bug!("Exhaustiveness check returned no witnesses")
1071 pats.into_iter().map(|w| w.single_pattern()).collect()
1074 Useful(_) => bug!(),
1076 UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses }