|
78 | 78 | //! new pattern `p`.
|
79 | 79 | //!
|
80 | 80 | //! For example, say we have the following:
|
| 81 | +//! |
81 | 82 | //! ```
|
82 |
| -//! // x: (Option<bool>, Result<()>) |
83 |
| -//! match x { |
84 |
| -//! (Some(true), _) => {} |
85 |
| -//! (None, Err(())) => {} |
86 |
| -//! (None, Err(_)) => {} |
87 |
| -//! } |
| 83 | +//! // x: (Option<bool>, Result<()>) |
| 84 | +//! match x { |
| 85 | +//! (Some(true), _) => {} |
| 86 | +//! (None, Err(())) => {} |
| 87 | +//! (None, Err(_)) => {} |
| 88 | +//! } |
88 | 89 | //! ```
|
| 90 | +//! |
89 | 91 | //! Here, the matrix `P` starts as:
|
| 92 | +//! |
| 93 | +//! ``` |
90 | 94 | //! [
|
91 | 95 | //! [(Some(true), _)],
|
92 | 96 | //! [(None, Err(()))],
|
93 | 97 | //! [(None, Err(_))],
|
94 | 98 | //! ]
|
| 99 | +//! ``` |
| 100 | +//! |
95 | 101 | //! We can tell it's not exhaustive, because `U(P, _)` is true (we're not covering
|
96 | 102 | //! `[(Some(false), _)]`, for instance). In addition, row 3 is not useful, because
|
97 | 103 | //! all the values it covers are already covered by row 2.
|
|
178 | 184 | //! This special case is handled in `is_useful_specialized`.
|
179 | 185 | //!
|
180 | 186 | //! For example, if `P` is:
|
| 187 | +//! |
| 188 | +//! ``` |
181 | 189 | //! [
|
182 |
| -//! [Some(true), _], |
183 |
| -//! [None, 0], |
| 190 | +//! [Some(true), _], |
| 191 | +//! [None, 0], |
184 | 192 | //! ]
|
| 193 | +//! ``` |
| 194 | +//! |
185 | 195 | //! and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
|
186 | 196 | //! matches values that row 2 doesn't. For row 1 however, we need to dig into the
|
187 | 197 | //! arguments of `Some` to know whether some new value is covered. So we compute
|
|
198 | 208 | //! `U(P, p) := U(D(P), D(p))`
|
199 | 209 | //!
|
200 | 210 | //! For example, if `P` is:
|
| 211 | +//! |
| 212 | +//! ``` |
201 | 213 | //! [
|
202 | 214 | //! [_, true, _],
|
203 | 215 | //! [None, false, 1],
|
204 | 216 | //! ]
|
| 217 | +//! ``` |
| 218 | +//! |
205 | 219 | //! and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
|
206 | 220 | //! only had row 2, we'd know that `p` is useful. However row 1 starts with a
|
207 | 221 | //! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
|
|
215 | 229 | //! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
|
216 | 230 | //!
|
217 | 231 | //! For example, if `P` is:
|
| 232 | +//! |
| 233 | +//! ``` |
218 | 234 | //! [
|
219 | 235 | //! [Some(true), _],
|
220 | 236 | //! [None, false],
|
221 | 237 | //! ]
|
| 238 | +//! ``` |
| 239 | +//! |
222 | 240 | //! and `p` is [_, false], both `None` and `Some` constructors appear in the first
|
223 | 241 | //! components of `P`. We will therefore try popping both constructors in turn: we
|
224 | 242 | //! compute `U([[true, _]], [_, false])` for the `Some` constructor, and `U([[false]],
|
@@ -1496,6 +1514,7 @@ struct PatCtxt<'tcx> {
|
1496 | 1514 | /// multiple patterns.
|
1497 | 1515 | ///
|
1498 | 1516 | /// For example, if we are constructing a witness for the match against
|
| 1517 | +/// |
1499 | 1518 | /// ```
|
1500 | 1519 | /// struct Pair(Option<(u32, u32)>, bool);
|
1501 | 1520 | ///
|
@@ -1619,12 +1638,14 @@ fn all_constructors<'a, 'tcx>(
|
1619 | 1638 | // actually match against them all themselves. So we always return only the fictitious
|
1620 | 1639 | // constructor.
|
1621 | 1640 | // E.g., in an example like:
|
| 1641 | + // |
1622 | 1642 | // ```
|
1623 | 1643 | // let err: io::ErrorKind = ...;
|
1624 | 1644 | // match err {
|
1625 | 1645 | // io::ErrorKind::NotFound => {},
|
1626 | 1646 | // }
|
1627 | 1647 | // ```
|
| 1648 | + // |
1628 | 1649 | // we don't want to show every possible IO error, but instead have only `_` as the
|
1629 | 1650 | // witness.
|
1630 | 1651 | let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);
|
@@ -2017,6 +2038,7 @@ crate fn is_useful<'p, 'tcx>(
|
2017 | 2038 | let mut unreachable_branches = Vec::new();
|
2018 | 2039 | // Subpatterns that are unreachable from all branches. E.g. in the following case, the last
|
2019 | 2040 | // `true` is unreachable only from one branch, so it is overall reachable.
|
| 2041 | + // |
2020 | 2042 | // ```
|
2021 | 2043 | // match (true, true) {
|
2022 | 2044 | // (true, true) => {}
|
@@ -2161,10 +2183,12 @@ crate fn is_useful<'p, 'tcx>(
|
2161 | 2183 | // to do this and instead report a single `_` witness:
|
2162 | 2184 | // if the user didn't actually specify a constructor
|
2163 | 2185 | // in this arm, e.g., in
|
| 2186 | + // |
2164 | 2187 | // ```
|
2165 | 2188 | // let x: (Direction, Direction, bool) = ...;
|
2166 | 2189 | // let (_, _, false) = x;
|
2167 | 2190 | // ```
|
| 2191 | + // |
2168 | 2192 | // we don't want to show all 16 possible witnesses
|
2169 | 2193 | // `(<direction-1>, <direction-2>, true)` - we are
|
2170 | 2194 | // satisfied with `(_, _, true)`. In this case,
|
|
0 commit comments