@@ -351,15 +351,38 @@ impl<'tcx> Witness<'tcx> {
351
351
ty : Ty < ' tcx > )
352
352
-> Self
353
353
{
354
- let sub_pattern_tys = constructor_sub_pattern_tys ( cx, ctor, ty) ;
355
- self . 0 . extend ( sub_pattern_tys. into_iter ( ) . map ( |ty| {
356
- Pattern {
357
- ty,
358
- span : DUMMY_SP ,
359
- kind : box PatternKind :: Wild ,
354
+ // If we've been trying to exhaustively match over the domain of values for a type,
355
+ // then we can construct witnesses directly corresponding to the missing ranges of values,
356
+ // giving far more precise diagnostics.
357
+ // `ConstantValue` and `ConstantRange` only occur in practice when doing exhaustive value
358
+ // matching (exhaustive_integer_patterns).
359
+ match ctor {
360
+ ConstantValue ( value) => {
361
+ Witness ( vec ! [ Pattern {
362
+ ty,
363
+ span: DUMMY_SP ,
364
+ kind: box PatternKind :: Constant { value } ,
365
+ } ] )
366
+ }
367
+ ConstantRange ( lo, hi, end) => {
368
+ Witness ( vec ! [ Pattern {
369
+ ty,
370
+ span: DUMMY_SP ,
371
+ kind: box PatternKind :: Range { lo, hi, end: * end } ,
372
+ } ] )
360
373
}
361
- } ) ) ;
362
- self . apply_constructor ( cx, ctor, ty)
374
+ _ => {
375
+ let sub_pattern_tys = constructor_sub_pattern_tys ( cx, ctor, ty) ;
376
+ self . 0 . extend ( sub_pattern_tys. into_iter ( ) . map ( |ty| {
377
+ Pattern {
378
+ ty,
379
+ span : DUMMY_SP ,
380
+ kind : box PatternKind :: Wild ,
381
+ }
382
+ } ) ) ;
383
+ self . apply_constructor ( cx, ctor, ty)
384
+ }
385
+ }
363
386
}
364
387
365
388
@@ -976,7 +999,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
976
999
// `used_ctors` is empty.
977
1000
let new_witnesses = if is_non_exhaustive || used_ctors. is_empty ( ) {
978
1001
// All constructors are unused. Add wild patterns
979
- // rather than each individual constructor
1002
+ // rather than each individual constructor.
980
1003
pats. into_iter ( ) . map ( |mut witness| {
981
1004
witness. 0 . push ( Pattern {
982
1005
ty : pcx. ty ,
@@ -986,46 +1009,15 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
986
1009
witness
987
1010
} ) . collect ( )
988
1011
} else {
989
- if consider_value_constructors {
990
- // If we've been trying to exhaustively match
991
- // over the domain of values for a type,
992
- // then we can provide better diagnostics
993
- // regarding which values were missing.
994
- missing_ctors. into_iter ( ) . map ( |ctor| {
995
- match ctor {
996
- // A constant range of length 1 is simply
997
- // a constant value.
998
- ConstantValue ( value) => {
999
- Witness ( vec ! [ Pattern {
1000
- ty: pcx. ty,
1001
- span: DUMMY_SP ,
1002
- kind: box PatternKind :: Constant { value } ,
1003
- } ] )
1004
- }
1005
- // We always report missing intervals
1006
- // in terms of inclusive ranges.
1007
- ConstantRange ( lo, hi, end) => {
1008
- Witness ( vec ! [ Pattern {
1009
- ty: pcx. ty,
1010
- span: DUMMY_SP ,
1011
- kind: box PatternKind :: Range { lo, hi, end } ,
1012
- } ] )
1013
- } ,
1014
- _ => bug ! ( "`ranges_subtract_pattern` should only produce \
1015
- `ConstantRange`s") ,
1016
- }
1017
- } ) . collect ( )
1018
- } else {
1019
- pats. into_iter ( ) . flat_map ( |witness| {
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(_)`.
1025
- witness. clone ( ) . push_wild_constructor ( cx, ctor, pcx. ty )
1026
- } )
1027
- } ) . collect ( )
1028
- }
1012
+ pats. into_iter ( ) . flat_map ( |witness| {
1013
+ missing_ctors. iter ( ) . map ( move |ctor| {
1014
+ // Extends the witness with a "wild" version of this
1015
+ // constructor, that matches everything that can be built with
1016
+ // it. For example, if `ctor` is a `Constructor::Variant` for
1017
+ // `Option::Some`, this pushes the witness for `Some(_)`.
1018
+ witness. clone ( ) . push_wild_constructor ( cx, ctor, pcx. ty )
1019
+ } )
1020
+ } ) . collect ( )
1029
1021
} ;
1030
1022
UsefulWithWitness ( new_witnesses)
1031
1023
}
0 commit comments