@@ -846,15 +846,14 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
846
846
847
847
#[ derive( Clone , Debug ) ]
848
848
enum 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`.
851
853
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.
855
856
WithWitnesses ( Vec < Witness < ' tcx > > ) ,
856
- /// When carrying witnesses, indicates that the whole pattern is unreachable.
857
- WithWitnessesEmpty ,
858
857
}
859
858
860
859
impl < ' p , ' tcx > Usefulness < ' p , ' tcx > {
@@ -866,27 +865,19 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
866
865
}
867
866
fn new_not_useful ( preference : WitnessPreference ) -> Self {
868
867
match preference {
869
- ConstructWitness => WithWitnessesEmpty ,
870
- LeaveOutWitness => NoWitnessesFull ,
868
+ ConstructWitness => WithWitnesses ( vec ! [ ] ) ,
869
+ LeaveOutWitness => NoWitnesses ( SubPatSet :: full ( ) ) ,
871
870
}
872
871
}
873
872
874
873
/// Combine usefulnesses from two branches. This is an associative operation.
875
874
fn extend ( & mut self , other : Self ) {
876
875
match ( & mut * self , other) {
876
+ ( WithWitnesses ( _) , WithWitnesses ( o) ) if o. is_empty ( ) => { }
877
+ ( WithWitnesses ( s) , WithWitnesses ( o) ) if s. is_empty ( ) => * self = WithWitnesses ( o) ,
877
878
( WithWitnesses ( s) , WithWitnesses ( o) ) => s. extend ( o) ,
878
- ( WithWitnessesEmpty , WithWitnesses ( o) ) => * self = WithWitnesses ( o) ,
879
- ( WithWitnesses ( _) , WithWitnessesEmpty ) => { }
880
- ( WithWitnessesEmpty , WithWitnessesEmpty ) => { }
881
-
882
879
( 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 ! ( ) ,
890
881
}
891
882
}
892
883
@@ -909,12 +900,10 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
909
900
/// After calculating the usefulness for a branch of an or-pattern, call this to make this
910
901
/// usefulness mergeable with those from the other branches.
911
902
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
+ }
918
907
}
919
908
920
909
/// After calculating usefulness after a specialization, call this to recontruct a usefulness
@@ -928,6 +917,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
928
917
ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
929
918
) -> Self {
930
919
match self {
920
+ WithWitnesses ( witnesses) if witnesses. is_empty ( ) => WithWitnesses ( witnesses) ,
931
921
WithWitnesses ( witnesses) => {
932
922
let new_witnesses = if matches ! ( ctor, Constructor :: Missing ) {
933
923
let mut split_wildcard = SplitWildcard :: new ( pcx) ;
@@ -961,8 +951,6 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
961
951
WithWitnesses ( new_witnesses)
962
952
}
963
953
NoWitnesses ( subpats) => NoWitnesses ( subpats. unspecialize ( ctor_wild_subpatterns. len ( ) ) ) ,
964
- NoWitnessesFull => NoWitnessesFull ,
965
- WithWitnessesEmpty => WithWitnessesEmpty ,
966
954
}
967
955
}
968
956
}
@@ -1209,8 +1197,7 @@ crate fn compute_match_usefulness<'p, 'tcx>(
1209
1197
let reachability = match usefulness {
1210
1198
NoWitnesses ( subpats) if subpats. is_full ( ) => Reachability :: Unreachable ,
1211
1199
NoWitnesses ( subpats) => Reachability :: Reachable ( subpats. to_spans ( ) . unwrap ( ) ) ,
1212
- NoWitnessesFull => Reachability :: Unreachable ,
1213
- WithWitnesses ( ..) | WithWitnessesEmpty => bug ! ( ) ,
1200
+ WithWitnesses ( ..) => bug ! ( ) ,
1214
1201
} ;
1215
1202
( arm, reachability)
1216
1203
} )
@@ -1220,15 +1207,8 @@ crate fn compute_match_usefulness<'p, 'tcx>(
1220
1207
let v = PatStack :: from_pattern ( wild_pattern) ;
1221
1208
let usefulness = is_useful ( cx, & matrix, & v, ConstructWitness , scrut_hir_id, false , true ) ;
1222
1209
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 ! ( ) ,
1232
1212
} ;
1233
1213
UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses }
1234
1214
}
0 commit comments