|
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