@@ -303,7 +303,38 @@ struct PatternContext<'tcx> {
303
303
max_slice_length : u64 ,
304
304
}
305
305
306
- /// A stack of patterns in reverse order of construction
306
+ /// A witness of non-exhaustiveness for error reporting, represented
307
+ /// as a list of patterns (in reverse order of construction) with
308
+ /// wildcards inside to represent elements that can take any inhabitant
309
+ /// of the type as a value.
310
+ ///
311
+ /// A witness against a list of patterns should have the same types
312
+ /// and length as the pattern matched against. Because Rust `match`
313
+ /// is always against a single pattern, at the end the witness will
314
+ /// have length 1, but in the middle of the algorithm, it can contain
315
+ /// multiple patterns.
316
+ ///
317
+ /// For example, if we are constructing a witness for the match against
318
+ /// ```
319
+ /// struct Pair(Option<(u32, u32)>, bool);
320
+ ///
321
+ /// match (p: Pair) {
322
+ /// Pair(None, _) => {}
323
+ /// Pair(_, false) => {}
324
+ /// }
325
+ /// ```
326
+ ///
327
+ /// We'll perform the following steps:
328
+ /// 1. Start with an empty witness
329
+ /// `Witness(vec![])`
330
+ /// 2. Push a witness `Some(_)` against the `None`
331
+ /// `Witness(vec![Some(_)])`
332
+ /// 3. Push a witness `true` against the `false`
333
+ /// `Witness(vec![Some(_), true])`
334
+ /// 4. Apply the `Pair` constructor to the witnesses
335
+ /// `Witness(vec![Pair(Some(_), true)])`
336
+ ///
337
+ /// The final `Pair(Some(_), true)` is then the resulting witness.
307
338
#[ derive( Clone , Debug ) ]
308
339
pub struct Witness < ' tcx > ( Vec < Pattern < ' tcx > > ) ;
309
340
@@ -987,6 +1018,10 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
987
1018
} else {
988
1019
pats. into_iter ( ) . flat_map ( |witness| {
989
1020
missing_ctors. iter ( ) . map ( move |ctor| {
1021
+ // Extends the witness with a "wild" version of this
1022
+ // constructor, that matches everything that can be built with
1023
+ // it. For example, if `ctor` is a `Constructor::Variant` for
1024
+ // `Option::Some`, this pushes the witness for `Some(_)`.
990
1025
witness. clone ( ) . push_wild_constructor ( cx, ctor, pcx. ty )
991
1026
} )
992
1027
} ) . collect ( )
0 commit comments