Skip to content

Commit fd3ec66

Browse files
committed
Integrate comment fixes suggested by arielb1
1 parent b052036 commit fd3ec66

File tree

1 file changed

+58
-7
lines changed

1 file changed

+58
-7
lines changed

src/librustc_mir/hair/pattern/_match.rs

+58-7
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,59 @@
222222
/// wildcards. Thus this mostly extends the original algorithm to ranges and variable-length
223223
/// slices, while removing the special-casing of the wildcard pattern. We also additionally
224224
/// support uninhabited types.
225+
///
226+
///
227+
/// # Handling of missing constructors (MISSING-CTOR)
228+
///
229+
/// This algorithm can be seen to essentially explore the full decision tree of patterns, except in
230+
/// the case where it "takes a shortcut" to find a "missing" constructor - that is, a constructor
231+
/// that is not covered by any of the non-wildcard patterns.
232+
///
233+
/// For example, in the following case:
234+
/// ```rust
235+
/// match x {
236+
/// (_, false) => {}
237+
/// (None, false) => {}
238+
/// }
239+
/// ```
240+
///
241+
/// The algorithm proceeds as follows:
242+
/// ```
243+
/// M = [ [(_, false)],
244+
/// [(None, false)]]
245+
/// p = [_]
246+
/// -- expand tuple (ctor = Simple)
247+
/// M = [ [_, false],
248+
/// [None, false]]
249+
/// p = [_, _]
250+
/// -- `Some(_)` is a missing ctor, dropping all the non-wildcard arms
251+
/// M = [ [false]]
252+
/// p = [_]
253+
/// -- `true` is a possible witness
254+
/// M = []
255+
/// p = []
256+
/// return "[]"
257+
/// return "[true]"
258+
/// return "[Some(_), true]"
259+
/// return "[(Some(_), true)]"
260+
/// ```
261+
///
262+
/// Once it finds that `Some(_)` is a missing constructor, it does not need to look any further -
263+
/// any witness using a non-missing constructor can be transformed to a witness using a missing
264+
/// constructor - and therefore it does not try to look for witnesses involving the other
265+
/// constructors - in this case, the `(None, true)` witness (which can be "transformed" to
266+
/// `(Some(_), true)`).
267+
///
268+
/// In the code, missing constructors are represented by the `Wildcard` and `MissingConstructors`
269+
/// variants of `Constructor`, with the difference between them being down to error reporting:
270+
/// `MissingConstructors` "remembers" the set of constructors it contains for error reporting (so
271+
/// we can show the `... not covered` error message), while `Wildcard` doesn't.
272+
///
273+
/// Therefore, `Wildcard` is used in cases where the exact constructor doesn't matter - either
274+
/// where the head column of the matrix contains only wildcards (and therefore, *every* constructor
275+
/// will work) or when the enum is `#[non_exhaustive]`, and therefore from a user POV there can
276+
/// always assumed to be an "fresh" constructor that will be useful for the witness.
277+
/// `MissingConstructors` is used in the other cases.
225278
use self::Constructor::*;
226279
use self::Usefulness::*;
227280
use self::WitnessPreference::*;
@@ -1821,6 +1874,7 @@ fn pat_constructors<'tcx>(
18211874
Variant(adt_def.variants[variant_index].def_id)
18221875
}
18231876
PatKind::Constant { value } => {
1877+
// FIXME: consts are not handled properly; see #65413
18241878
if let Some(range) = IntRange::from_const(tcx, param_env, value) {
18251879
IntRange(range)
18261880
} else {
@@ -2005,12 +2059,9 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20052059
}
20062060

20072061
if let Wildcard | MissingConstructors(_) = constructor {
2008-
// If `constructor` is `Wildcard`: either there were only wildcards in the first component
2009-
// of the matrix, or we are in a special non_exhaustive case where we pretend the type has
2010-
// an extra `_` constructor to prevent exhaustive matching. In both cases, all non-wildcard
2011-
// constructors should be discarded.
2012-
// If `constructor` is `MissingConstructors(_)`: by the invariant of MissingConstructors,
2013-
// we know that all non-wildcard constructors should be discarded.
2062+
// Both those cases capture a set of constructors that are not present in the head of
2063+
// current matrix. This means that we discard all non-wildcard constructors.
2064+
// See (MISSING-CTOR) at the top of the file for more details.
20142065
return match *pat.kind {
20152066
PatKind::Binding { .. } | PatKind::Wild => Some(PatStack::empty()),
20162067
_ => None,
@@ -2057,7 +2108,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20572108
(data, Size::from_bytes(start as u64), (end - start) as u64, t)
20582109
}
20592110
ConstValue::ByRef { .. } => {
2060-
// FIXME(oli-obk): implement `deref` for `ConstValue`
2111+
// FIXME(oli-obk): implement `deref` for `ConstValue`. See #53708
20612112
return None;
20622113
}
20632114
_ => span_bug!(

0 commit comments

Comments
 (0)