@@ -35,6 +35,7 @@ use arena::TypedArena;
35
35
use std:: cmp:: { self , Ordering } ;
36
36
use std:: fmt;
37
37
use std:: iter:: { FromIterator , IntoIterator } ;
38
+ use std:: ops:: RangeInclusive ;
38
39
39
40
pub fn expand_pattern < ' a , ' tcx > ( cx : & MatchCheckCtxt < ' a , ' tcx > , pat : Pattern < ' tcx > )
40
41
-> & ' a Pattern < ' tcx >
@@ -274,7 +275,7 @@ impl<'tcx> Constructor<'tcx> {
274
275
}
275
276
}
276
277
277
- #[ derive( Clone ) ]
278
+ #[ derive( Clone , Debug ) ]
278
279
pub enum Usefulness < ' tcx > {
279
280
Useful ,
280
281
UsefulWithWitness ( Vec < Witness < ' tcx > > ) ,
@@ -290,7 +291,7 @@ impl<'tcx> Usefulness<'tcx> {
290
291
}
291
292
}
292
293
293
- #[ derive( Copy , Clone ) ]
294
+ #[ derive( Copy , Clone , Debug ) ]
294
295
pub enum WitnessPreference {
295
296
ConstructWitness ,
296
297
LeaveOutWitness
@@ -303,7 +304,7 @@ struct PatternContext<'tcx> {
303
304
}
304
305
305
306
/// A stack of patterns in reverse order of construction
306
- #[ derive( Clone ) ]
307
+ #[ derive( Clone , Debug ) ]
307
308
pub struct Witness < ' tcx > ( Vec < Pattern < ' tcx > > ) ;
308
309
309
310
impl < ' tcx > Witness < ' tcx > {
@@ -418,10 +419,6 @@ impl<'tcx> Witness<'tcx> {
418
419
/// but is instead bounded by the maximum fixed length of slice patterns in
419
420
/// the column of patterns being analyzed.
420
421
///
421
- /// This intentionally does not list ConstantValue specializations for
422
- /// non-booleans, because we currently assume that there is always a
423
- /// "non-standard constant" that matches. See issue #12483.
424
- ///
425
422
/// We make sure to omit constructors that are statically impossible. eg for
426
423
/// Option<!> we do not include Some(_) in the returned list of constructors.
427
424
fn all_constructors < ' a , ' tcx : ' a > ( cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
@@ -530,7 +527,7 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
530
527
// `[true, ..]`
531
528
// `[.., false]`
532
529
// Then any slice of length ≥1 that matches one of these two
533
- // patterns can be be trivially turned to a slice of any
530
+ // patterns can be trivially turned to a slice of any
534
531
// other length ≥1 that matches them and vice-versa - for
535
532
// but the slice from length 2 `[false, true]` that matches neither
536
533
// of these patterns can't be turned to a slice from length 1 that
@@ -823,33 +820,32 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
823
820
// as patterns in the `match` expression, but did not.
824
821
let mut missing_ctors = vec ! [ ] ;
825
822
for req_ctor in & all_ctors {
826
- if consider_value_constructors {
827
- let mut refined_ctors = vec ! [ req_ctor. clone( ) ] ;
828
- for used_ctor in & used_ctors {
829
- // Refine the required constructors for the type by subtracting
830
- // the range defined by the current constructor pattern.
831
- refined_ctors = match IntRange :: from_ctor ( cx. tcx , used_ctor) {
832
- Some ( interval) => interval. subtract_from ( cx. tcx , refined_ctors) ,
833
- None => refined_ctors,
834
- } ;
835
- // If the constructor patterns that have been considered so far
836
- // already cover the entire range of values, then we the
837
- // constructor is not missing, and we can move on to the next one.
838
- if refined_ctors. is_empty ( ) {
839
- break ;
823
+ let mut refined_ctors = vec ! [ req_ctor. clone( ) ] ;
824
+ for used_ctor in & used_ctors {
825
+ if used_ctor == req_ctor {
826
+ // If a constructor appears in a `match` arm, we can
827
+ // eliminate it straight away.
828
+ refined_ctors = vec ! [ ]
829
+ } else if exhaustive_integer_patterns {
830
+ if let Some ( interval) = IntRange :: from_ctor ( cx. tcx , used_ctor) {
831
+ // Refine the required constructors for the type by subtracting
832
+ // the range defined by the current constructor pattern.
833
+ refined_ctors = interval. subtract_from ( cx. tcx , refined_ctors) ;
840
834
}
841
835
}
842
- // If a constructor has not been matched, then it is missing.
843
- // We add `refined_ctors` instead of `req_ctor`, because then we can
844
- // provide more detailed error information about precisely which
845
- // ranges have been omitted.
846
- missing_ctors. extend ( refined_ctors) ;
847
- } else {
848
- // A constructor is missing if it never appears in a `match` arm.
849
- if !used_ctors. iter ( ) . any ( |used_ctor| used_ctor == req_ctor) {
850
- missing_ctors. push ( req_ctor. clone ( ) ) ;
836
+
837
+ // If the constructor patterns that have been considered so far
838
+ // already cover the entire range of values, then we the
839
+ // constructor is not missing, and we can move on to the next one.
840
+ if refined_ctors. is_empty ( ) {
841
+ break ;
851
842
}
852
843
}
844
+ // If a constructor has not been matched, then it is missing.
845
+ // We add `refined_ctors` instead of `req_ctor`, because then we can
846
+ // provide more detailed error information about precisely which
847
+ // ranges have been omitted.
848
+ missing_ctors. extend ( refined_ctors) ;
853
849
}
854
850
855
851
// `missing_ctors` is the set of constructors from the same type as the
0 commit comments