@@ -624,27 +624,25 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
624
624
/// `self.is_empty()` we ensure that `self` is `Empty`, and same with `Full`. This is not important
625
625
/// for correctness currently.
626
626
#[ derive( Debug , Clone ) ]
627
- enum SubPatSet < ' p , ' tcx > {
627
+ enum SubPatSet {
628
628
/// The empty set. This means the pattern is unreachable.
629
629
Empty ,
630
630
/// The set containing the full pattern.
631
631
Full ,
632
632
/// If the pattern is a pattern with a constructor or a pattern-stack, we store a set for each
633
633
/// of its subpatterns. Missing entries in the map are implicitly full, because that's the
634
634
/// common case.
635
- Seq { subpats : FxHashMap < usize , SubPatSet < ' p , ' tcx > > } ,
635
+ Seq { subpats : FxHashMap < usize , SubPatSet > } ,
636
636
/// If the pattern is an or-pattern, we store a set for each of its alternatives. Missing
637
637
/// entries in the map are implicitly empty. Note: we always flatten nested or-patterns.
638
638
Alt {
639
- subpats : FxHashMap < usize , SubPatSet < ' p , ' tcx > > ,
640
- /// Counts the total number of alternatives in the pattern
641
- alt_count : usize ,
642
- /// We keep the pattern around to retrieve spans.
643
- pat : & ' p Pat < ' tcx > ,
639
+ subpats : FxHashMap < usize , SubPatSet > ,
640
+ /// Span of each alternative in the pattern
641
+ spans : Vec < Span > ,
644
642
} ,
645
643
}
646
644
647
- impl < ' p , ' tcx > SubPatSet < ' p , ' tcx > {
645
+ impl SubPatSet {
648
646
fn full ( ) -> Self {
649
647
SubPatSet :: Full
650
648
}
@@ -670,8 +668,8 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
670
668
// The whole pattern is reachable only when all its alternatives are.
671
669
SubPatSet :: Seq { subpats } => subpats. values ( ) . all ( |sub_set| sub_set. is_full ( ) ) ,
672
670
// The whole or-pattern is reachable only when all its alternatives are.
673
- SubPatSet :: Alt { subpats, alt_count , .. } => {
674
- subpats. len ( ) == * alt_count && subpats. values ( ) . all ( |set| set. is_full ( ) )
671
+ SubPatSet :: Alt { subpats, spans , .. } => {
672
+ subpats. len ( ) == spans . len ( ) && subpats. values ( ) . all ( |set| set. is_full ( ) )
675
673
}
676
674
}
677
675
}
@@ -726,7 +724,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
726
724
/// whole pattern is unreachable) we return `None`.
727
725
fn list_unreachable_spans ( & self ) -> Option < Vec < Span > > {
728
726
/// Panics if `set.is_empty()`.
729
- fn fill_spans ( set : & SubPatSet < ' _ , ' _ > , spans : & mut Vec < Span > ) {
727
+ fn fill_spans ( set : & SubPatSet , spans : & mut Vec < Span > ) {
730
728
match set {
731
729
SubPatSet :: Empty => bug ! ( ) ,
732
730
SubPatSet :: Full => { }
@@ -735,13 +733,12 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
735
733
fill_spans ( sub_set, spans) ;
736
734
}
737
735
}
738
- SubPatSet :: Alt { subpats, pat, alt_count, .. } => {
739
- let expanded = expand_or_pat ( pat) ;
740
- for i in 0 ..* alt_count {
736
+ SubPatSet :: Alt { subpats, spans : alt_spans, .. } => {
737
+ for ( i, span) in alt_spans. iter ( ) . enumerate ( ) {
741
738
let sub_set = subpats. get ( & i) . unwrap_or ( & SubPatSet :: Empty ) ;
742
739
if sub_set. is_empty ( ) {
743
740
// Found an unreachable subpattern.
744
- spans. push ( expanded [ i ] . span ) ;
741
+ spans. push ( * span) ;
745
742
} else {
746
743
fill_spans ( sub_set, spans) ;
747
744
}
@@ -806,7 +803,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
806
803
/// Here `None` would return the full set and `Some(true | false)` would return the set
807
804
/// containing `false`. After `unsplit_or_pat`, we want the set to contain `None` and `false`.
808
805
/// This is what this function does.
809
- fn unsplit_or_pat ( mut self , alt_id : usize , alt_count : usize , pat : & ' p Pat < ' tcx > ) -> Self {
806
+ fn unsplit_or_pat ( mut self , alt_id : usize , spans : Vec < Span > ) -> Self {
810
807
use SubPatSet :: * ;
811
808
if self . is_empty ( ) {
812
809
return Empty ;
@@ -822,7 +819,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
822
819
} ;
823
820
let mut subpats_first_col = FxHashMap :: default ( ) ;
824
821
subpats_first_col. insert ( alt_id, set_first_col) ;
825
- let set_first_col = Alt { subpats : subpats_first_col, pat , alt_count } ;
822
+ let set_first_col = Alt { subpats : subpats_first_col, spans } ;
826
823
827
824
let mut subpats = match self {
828
825
Full => FxHashMap :: default ( ) ,
@@ -842,19 +839,19 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
842
839
/// witnesses of non-exhaustiveness when there are any.
843
840
/// Which variant to use is dictated by `ArmType`.
844
841
#[ derive( Clone , Debug ) ]
845
- enum Usefulness < ' p , ' tcx > {
842
+ enum Usefulness < ' tcx > {
846
843
/// Carries a set of subpatterns that have been found to be reachable. If empty, this indicates
847
844
/// the whole pattern is unreachable. If not, this indicates that the pattern is reachable but
848
845
/// that some sub-patterns may be unreachable (due to or-patterns). In the absence of
849
846
/// or-patterns this will always be either `Empty` (the whole pattern is unreachable) or `Full`
850
847
/// (the whole pattern is reachable).
851
- NoWitnesses ( SubPatSet < ' p , ' tcx > ) ,
848
+ NoWitnesses ( SubPatSet ) ,
852
849
/// Carries a list of witnesses of non-exhaustiveness. If empty, indicates that the whole
853
850
/// pattern is unreachable.
854
851
WithWitnesses ( Vec < Witness < ' tcx > > ) ,
855
852
}
856
853
857
- impl < ' p , ' tcx > Usefulness < ' p , ' tcx > {
854
+ impl < ' tcx > Usefulness < ' tcx > {
858
855
fn new_useful ( preference : ArmType ) -> Self {
859
856
match preference {
860
857
FakeExtraWildcard => WithWitnesses ( vec ! [ Witness ( vec![ ] ) ] ) ,
@@ -889,17 +886,17 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
889
886
890
887
/// After calculating the usefulness for a branch of an or-pattern, call this to make this
891
888
/// usefulness mergeable with those from the other branches.
892
- fn unsplit_or_pat ( self , alt_id : usize , alt_count : usize , pat : & ' p Pat < ' tcx > ) -> Self {
889
+ fn unsplit_or_pat ( self , alt_id : usize , spans : Vec < Span > ) -> Self {
893
890
match self {
894
- NoWitnesses ( subpats) => NoWitnesses ( subpats. unsplit_or_pat ( alt_id, alt_count , pat ) ) ,
891
+ NoWitnesses ( subpats) => NoWitnesses ( subpats. unsplit_or_pat ( alt_id, spans ) ) ,
895
892
WithWitnesses ( _) => bug ! ( ) ,
896
893
}
897
894
}
898
895
899
896
/// After calculating usefulness after a specialization, call this to reconstruct a usefulness
900
897
/// that makes sense for the matrix pre-specialization. This new usefulness can then be merged
901
898
/// with the results of specializing with the other constructors.
902
- fn apply_constructor (
899
+ fn apply_constructor < ' p > (
903
900
self ,
904
901
pcx : PatCtxt < ' _ , ' p , ' tcx > ,
905
902
matrix : & Matrix < ' p , ' tcx > , // used to compute missing ctors
@@ -1099,7 +1096,7 @@ fn is_useful<'p, 'tcx>(
1099
1096
hir_id : HirId ,
1100
1097
is_under_guard : bool ,
1101
1098
is_top_level : bool ,
1102
- ) -> Usefulness < ' p , ' tcx > {
1099
+ ) -> Usefulness < ' tcx > {
1103
1100
debug ! ( "matrix,v={:?}{:?}" , matrix, v) ;
1104
1101
let Matrix { patterns : rows, .. } = matrix;
1105
1102
@@ -1129,15 +1126,14 @@ fn is_useful<'p, 'tcx>(
1129
1126
let mut ret = Usefulness :: new_not_useful ( witness_preference) ;
1130
1127
if is_or_pat ( v. head ( ) ) {
1131
1128
debug ! ( "expanding or-pattern" ) ;
1132
- let v_head = v. head ( ) ;
1133
1129
let vs: Vec < _ > = v. expand_or_pat ( ) . collect ( ) ;
1134
- let alt_count = vs. len ( ) ;
1130
+ let spans : Vec < _ > = vs. iter ( ) . map ( |pat| pat . head ( ) . span ) . collect ( ) ;
1135
1131
// We try each or-pattern branch in turn.
1136
1132
let mut matrix = matrix. clone ( ) ;
1137
1133
for ( i, v) in vs. into_iter ( ) . enumerate ( ) {
1138
1134
let usefulness =
1139
1135
is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard, false ) ;
1140
- let usefulness = usefulness. unsplit_or_pat ( i, alt_count , v_head ) ;
1136
+ let usefulness = usefulness. unsplit_or_pat ( i, spans . clone ( ) ) ;
1141
1137
ret. extend ( usefulness) ;
1142
1138
// If pattern has a guard don't add it to the matrix.
1143
1139
if !is_under_guard {
0 commit comments