@@ -926,7 +926,7 @@ impl<'tcx> WitnessMatrix<'tcx> {
926
926
}
927
927
928
928
/// Reverses specialization by the `Missing` constructor by pushing a whole new pattern.
929
- fn push_pattern ( & mut self , pat : & WitnessPat < ' tcx > ) {
929
+ fn push_pattern ( & mut self , pat : WitnessPat < ' tcx > ) {
930
930
for witness in self . 0 . iter_mut ( ) {
931
931
witness. push_pattern ( pat. clone ( ) )
932
932
}
@@ -942,31 +942,34 @@ impl<'tcx> WitnessMatrix<'tcx> {
942
942
if self . is_empty ( ) {
943
943
return ;
944
944
}
945
- if matches ! ( ctor , Constructor :: Wildcard ) {
946
- let pat = WitnessPat :: wild_from_ctor ( pcx , Constructor :: Wildcard ) ;
947
- self . push_pattern ( & pat ) ;
948
- } else if matches ! ( ctor , Constructor :: Missing ) {
949
- // We got the special `Missing` constructor, so each of the missing constructors gives a
950
- // new pattern that is not caught by the match. We list those patterns and push them
951
- // onto our current witnesses.
952
- if missing_ctors . iter ( ) . any ( |c| c . is_non_exhaustive ( ) ) {
953
- // We only report `_` here; listing other constructors would be redundant.
954
- let pat = WitnessPat :: wild_from_ctor ( pcx , Constructor :: NonExhaustive ) ;
955
- self . push_pattern ( & pat ) ;
956
- } else {
957
- let old_witnesses = std :: mem :: replace ( self , Self :: empty ( ) ) ;
958
- for ctor in missing_ctors {
959
- let pat = WitnessPat :: wild_from_ctor ( pcx , ctor . clone ( ) ) ;
960
- let mut witnesses_with_missing_ctor = old_witnesses . clone ( ) ;
961
- witnesses_with_missing_ctor . push_pattern ( & pat ) ;
962
- self . extend ( witnesses_with_missing_ctor )
945
+ if let Constructor :: Missing { report_individual_ctors } = ctor {
946
+ // We got the special `Missing` constructor that stands for the constructors not present
947
+ // in the match.
948
+ if * report_individual_ctors {
949
+ if missing_ctors . iter ( ) . any ( |c| c . is_non_exhaustive ( ) ) {
950
+ // We only report `_` here; listing other constructors would be redundant.
951
+ let pat = WitnessPat :: wild_from_ctor ( pcx , Constructor :: NonExhaustive ) ;
952
+ self . push_pattern ( pat ) ;
953
+ } else {
954
+ let old_witnesses = std :: mem :: replace ( self , Self :: empty ( ) ) ;
955
+ for ctor in missing_ctors {
956
+ // For each missing constructor `c`, we push a `c(_, _, _)` witness
957
+ // appropriately filled with wildcards.
958
+ let pat = WitnessPat :: wild_from_ctor ( pcx , ctor . clone ( ) ) ;
959
+ let mut witnesses_with_missing_ctor = old_witnesses . clone ( ) ;
960
+ witnesses_with_missing_ctor . push_pattern ( pat ) ;
961
+ self . extend ( witnesses_with_missing_ctor )
962
+ }
963
963
}
964
+ } else {
965
+ // Report only a wildcard.
966
+ let pat = WitnessPat :: wild_from_ctor ( pcx, Constructor :: Wildcard ) ;
967
+ self . push_pattern ( pat) ;
964
968
}
965
969
} else if !missing_ctors. is_empty ( ) {
966
- // `ctor` isn't `Wildcard` or `Missing` and some ctors are missing, so we know
967
- // `split_ctors` will contain `Wildcard` or `Missing`.
968
- // For diagnostic purposes we choose to discard witnesses we got under `ctor`, which
969
- // will let only the `Wildcard` or `Missing` be reported.
970
+ // `ctor` isn't `Missing` and some ctors are missing, so we know `split_ctors` will
971
+ // contain `Missing`. For diagnostic purposes we choose to discard witnesses we got
972
+ // under `ctor`, which will let only the `Missing` be reported.
970
973
self . 0 . clear ( ) ;
971
974
} else {
972
975
for witness in self . 0 . iter_mut ( ) {
@@ -1026,18 +1029,13 @@ fn compute_exhaustiveness_and_reachability<'p, 'tcx>(
1026
1029
let ctors = matrix. heads ( ) . map ( |p| p. ctor ( ) ) ;
1027
1030
let split_set = ConstructorSet :: for_ty ( pcx. cx , pcx. ty ) . split ( pcx, ctors) ;
1028
1031
let mut split_ctors = split_set. present ;
1029
- // We want to iterate over a full set of constructors, so if any is missing we add a wildcard.
1032
+ // We want to iterate over a full set of constructors, so if some are missing we add a `Missing`
1033
+ // to represent them.
1030
1034
if !split_set. missing . is_empty ( ) {
1031
1035
let all_missing = split_ctors. is_empty ( ) ;
1032
- let always_report_missing = is_top_level && !IntRange :: is_integral ( pcx. ty ) ;
1033
- let ctor = if all_missing && !always_report_missing {
1034
- Constructor :: Wildcard
1035
- } else {
1036
- // Like `Wildcard`, except if it doesn't match a row this will report all the missing
1037
- // constructors instead of just `_`.
1038
- Constructor :: Missing
1039
- } ;
1040
- split_ctors. push ( ctor) ;
1036
+ let always_report_all = is_top_level && !IntRange :: is_integral ( pcx. ty ) ;
1037
+ let report_individual_ctors = always_report_all || !all_missing;
1038
+ split_ctors. push ( Constructor :: Missing { report_individual_ctors } ) ;
1041
1039
}
1042
1040
1043
1041
let mut ret = WitnessMatrix :: empty ( ) ;
0 commit comments