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