@@ -846,15 +846,14 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
846846
847847#[ derive( Clone , Debug ) ]
848848enum Usefulness < ' p , ' tcx > {
849- /// Potentially carries a set of sub-branches that have been found to be unreachable. Used
850- /// only in the presence of or-patterns, otherwise it stays empty.
849+ /// Carries a set of subpatterns that have been found to be unreachable. If full, this
850+ /// indicates the whole pattern is unreachable. If not, this indicates that the pattern is
851+ /// reachable but has some unreachable sub-patterns (due to or-patterns). In the absence of
852+ /// or-patterns, this is either `Empty` or `Full`.
851853 NoWitnesses ( SubPatSet < ' p , ' tcx > ) ,
852- /// When not carrying witnesses, indicates that the whole pattern is unreachable.
853- NoWitnessesFull ,
854- /// Carries a list of witnesses of non-exhaustiveness. Non-empty.
854+ /// Carries a list of witnesses of non-exhaustiveness. If empty, indicates that the whole
855+ /// pattern is unreachable.
855856 WithWitnesses ( Vec < Witness < ' tcx > > ) ,
856- /// When carrying witnesses, indicates that the whole pattern is unreachable.
857- WithWitnessesEmpty ,
858857}
859858
860859impl < ' p , ' tcx > Usefulness < ' p , ' tcx > {
@@ -866,27 +865,19 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
866865 }
867866 fn new_not_useful ( preference : WitnessPreference ) -> Self {
868867 match preference {
869- ConstructWitness => WithWitnessesEmpty ,
870- LeaveOutWitness => NoWitnessesFull ,
868+ ConstructWitness => WithWitnesses ( vec ! [ ] ) ,
869+ LeaveOutWitness => NoWitnesses ( SubPatSet :: full ( ) ) ,
871870 }
872871 }
873872
874873 /// Combine usefulnesses from two branches. This is an associative operation.
875874 fn extend ( & mut self , other : Self ) {
876875 match ( & mut * self , other) {
876+ ( WithWitnesses ( _) , WithWitnesses ( o) ) if o. is_empty ( ) => { }
877+ ( WithWitnesses ( s) , WithWitnesses ( o) ) if s. is_empty ( ) => * self = WithWitnesses ( o) ,
877878 ( WithWitnesses ( s) , WithWitnesses ( o) ) => s. extend ( o) ,
878- ( WithWitnessesEmpty , WithWitnesses ( o) ) => * self = WithWitnesses ( o) ,
879- ( WithWitnesses ( _) , WithWitnessesEmpty ) => { }
880- ( WithWitnessesEmpty , WithWitnessesEmpty ) => { }
881-
882879 ( NoWitnesses ( s) , NoWitnesses ( o) ) => s. intersect ( o) ,
883- ( NoWitnessesFull , NoWitnesses ( o) ) => * self = NoWitnesses ( o) ,
884- ( NoWitnesses ( _) , NoWitnessesFull ) => { }
885- ( NoWitnessesFull , NoWitnessesFull ) => { }
886-
887- _ => {
888- unreachable ! ( )
889- }
880+ _ => unreachable ! ( ) ,
890881 }
891882 }
892883
@@ -909,12 +900,10 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
909900 /// After calculating the usefulness for a branch of an or-pattern, call this to make this
910901 /// usefulness mergeable with those from the other branches.
911902 fn unsplit_or_pat ( self , alt_id : usize , alt_count : usize , pat : & ' p Pat < ' tcx > ) -> Self {
912- let subpats = match self {
913- NoWitnesses ( subpats) => subpats,
914- NoWitnessesFull => SubPatSet :: full ( ) ,
915- WithWitnesses ( _) | WithWitnessesEmpty => bug ! ( ) ,
916- } ;
917- NoWitnesses ( subpats. unsplit_or_pat ( alt_id, alt_count, pat) )
903+ match self {
904+ NoWitnesses ( subpats) => NoWitnesses ( subpats. unsplit_or_pat ( alt_id, alt_count, pat) ) ,
905+ WithWitnesses ( _) => bug ! ( ) ,
906+ }
918907 }
919908
920909 /// After calculating usefulness after a specialization, call this to recontruct a usefulness
@@ -928,6 +917,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
928917 ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
929918 ) -> Self {
930919 match self {
920+ WithWitnesses ( witnesses) if witnesses. is_empty ( ) => WithWitnesses ( witnesses) ,
931921 WithWitnesses ( witnesses) => {
932922 let new_witnesses = if matches ! ( ctor, Constructor :: Missing ) {
933923 let mut split_wildcard = SplitWildcard :: new ( pcx) ;
@@ -961,8 +951,6 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
961951 WithWitnesses ( new_witnesses)
962952 }
963953 NoWitnesses ( subpats) => NoWitnesses ( subpats. unspecialize ( ctor_wild_subpatterns. len ( ) ) ) ,
964- NoWitnessesFull => NoWitnessesFull ,
965- WithWitnessesEmpty => WithWitnessesEmpty ,
966954 }
967955 }
968956}
@@ -1209,8 +1197,7 @@ crate fn compute_match_usefulness<'p, 'tcx>(
12091197 let reachability = match usefulness {
12101198 NoWitnesses ( subpats) if subpats. is_full ( ) => Reachability :: Unreachable ,
12111199 NoWitnesses ( subpats) => Reachability :: Reachable ( subpats. to_spans ( ) . unwrap ( ) ) ,
1212- NoWitnessesFull => Reachability :: Unreachable ,
1213- WithWitnesses ( ..) | WithWitnessesEmpty => bug ! ( ) ,
1200+ WithWitnesses ( ..) => bug ! ( ) ,
12141201 } ;
12151202 ( arm, reachability)
12161203 } )
@@ -1220,15 +1207,8 @@ crate fn compute_match_usefulness<'p, 'tcx>(
12201207 let v = PatStack :: from_pattern ( wild_pattern) ;
12211208 let usefulness = is_useful ( cx, & matrix, & v, ConstructWitness , scrut_hir_id, false , true ) ;
12221209 let non_exhaustiveness_witnesses = match usefulness {
1223- WithWitnessesEmpty => vec ! [ ] , // Wildcard pattern isn't useful, so the match is exhaustive.
1224- WithWitnesses ( pats) => {
1225- if pats. is_empty ( ) {
1226- bug ! ( "Exhaustiveness check returned no witnesses" )
1227- } else {
1228- pats. into_iter ( ) . map ( |w| w. single_pattern ( ) ) . collect ( )
1229- }
1230- }
1231- NoWitnesses ( _) | NoWitnessesFull => bug ! ( ) ,
1210+ WithWitnesses ( pats) => pats. into_iter ( ) . map ( |w| w. single_pattern ( ) ) . collect ( ) ,
1211+ NoWitnesses ( _) => bug ! ( ) ,
12321212 } ;
12331213 UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses }
12341214}
0 commit comments