@@ -713,13 +713,9 @@ impl<'tcx> Usefulness<'tcx> {
713
713
}
714
714
}
715
715
716
- fn is_useful ( & self ) -> bool {
717
- !matches ! ( * self , NotUseful )
718
- }
719
-
720
716
/// When trying several branches and each returns a `Usefulness`, we need to combine the
721
717
/// results together.
722
- fn merge ( usefulnesses : impl Iterator < Item = ( Self , Span ) > ) -> Self {
718
+ fn merge_or_patterns ( usefulnesses : impl Iterator < Item = ( Self , Span ) > ) -> Self {
723
719
// If we have detected some unreachable sub-branches, we only want to keep them when they
724
720
// were unreachable in _all_ branches. Eg. in the following, the last `true` is unreachable
725
721
// in the second branch of the first or-pattern, but not otherwise. Therefore we don't want
@@ -789,6 +785,27 @@ impl<'tcx> Usefulness<'tcx> {
789
785
}
790
786
}
791
787
788
+ /// When trying several branches and each returns a `Usefulness`, we need to combine the
789
+ /// results together.
790
+ fn merge_split_constructors ( usefulnesses : impl Iterator < Item = Self > ) -> Self {
791
+ // Witnesses of usefulness, if any.
792
+ let mut witnesses = Vec :: new ( ) ;
793
+
794
+ for u in usefulnesses {
795
+ match u {
796
+ Useful ( ..) => {
797
+ return u;
798
+ }
799
+ NotUseful => { }
800
+ UsefulWithWitness ( wits) => {
801
+ witnesses. extend ( wits) ;
802
+ }
803
+ }
804
+ }
805
+
806
+ if !witnesses. is_empty ( ) { UsefulWithWitness ( witnesses) } else { NotUseful }
807
+ }
808
+
792
809
fn apply_constructor < ' p > (
793
810
self ,
794
811
pcx : PatCtxt < ' _ , ' p , ' tcx > ,
@@ -975,29 +992,22 @@ fn is_useful<'p, 'tcx>(
975
992
}
976
993
( u, span)
977
994
} ) ;
978
- Usefulness :: merge ( usefulnesses)
995
+ Usefulness :: merge_or_patterns ( usefulnesses)
979
996
} else {
980
- v. head_ctor ( cx)
981
- . split ( pcx, Some ( hir_id) )
982
- . into_iter ( )
983
- . map ( |ctor| {
984
- // We cache the result of `Fields::wildcards` because it is used a lot.
985
- let ctor_wild_subpatterns = Fields :: wildcards ( pcx, & ctor) ;
986
- let matrix = pcx. matrix . specialize_constructor ( pcx, & ctor, & ctor_wild_subpatterns) ;
987
- let v = v. pop_head_constructor ( & ctor_wild_subpatterns) ;
988
- let usefulness = is_useful (
989
- pcx. cx ,
990
- & matrix,
991
- & v,
992
- witness_preference,
993
- hir_id,
994
- is_under_guard,
995
- false ,
996
- ) ;
997
- usefulness. apply_constructor ( pcx, & ctor, & ctor_wild_subpatterns)
998
- } )
999
- . find ( |result| result. is_useful ( ) )
1000
- . unwrap_or ( NotUseful )
997
+ // We split the head constructor of `v`.
998
+ let ctors = v. head_ctor ( cx) . split ( pcx, Some ( hir_id) ) ;
999
+ // For each constructor, we compute whether there's a value that starts with it that would
1000
+ // witness the usefulness of `v`.
1001
+ let usefulnesses = ctors. into_iter ( ) . map ( |ctor| {
1002
+ // We cache the result of `Fields::wildcards` because it is used a lot.
1003
+ let ctor_wild_subpatterns = Fields :: wildcards ( pcx, & ctor) ;
1004
+ let matrix = pcx. matrix . specialize_constructor ( pcx, & ctor, & ctor_wild_subpatterns) ;
1005
+ let v = v. pop_head_constructor ( & ctor_wild_subpatterns) ;
1006
+ let usefulness =
1007
+ is_useful ( pcx. cx , & matrix, & v, witness_preference, hir_id, is_under_guard, false ) ;
1008
+ usefulness. apply_constructor ( pcx, & ctor, & ctor_wild_subpatterns)
1009
+ } ) ;
1010
+ Usefulness :: merge_split_constructors ( usefulnesses)
1001
1011
} ;
1002
1012
debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix, v, ret) ;
1003
1013
ret
0 commit comments