@@ -624,27 +624,25 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
624624/// `self.is_empty()` we ensure that `self` is `Empty`, and same with `Full`. This is not important
625625/// for correctness currently.
626626#[ derive( Debug , Clone ) ]
627- enum SubPatSet < ' p , ' tcx > {
627+ enum SubPatSet {
628628 /// The empty set. This means the pattern is unreachable.
629629 Empty ,
630630 /// The set containing the full pattern.
631631 Full ,
632632 /// If the pattern is a pattern with a constructor or a pattern-stack, we store a set for each
633633 /// of its subpatterns. Missing entries in the map are implicitly full, because that's the
634634 /// common case.
635- Seq { subpats : FxHashMap < usize , SubPatSet < ' p , ' tcx > > } ,
635+ Seq { subpats : FxHashMap < usize , SubPatSet > } ,
636636 /// If the pattern is an or-pattern, we store a set for each of its alternatives. Missing
637637 /// entries in the map are implicitly empty. Note: we always flatten nested or-patterns.
638638 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 > ,
644642 } ,
645643}
646644
647- impl < ' p , ' tcx > SubPatSet < ' p , ' tcx > {
645+ impl SubPatSet {
648646 fn full ( ) -> Self {
649647 SubPatSet :: Full
650648 }
@@ -670,8 +668,8 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
670668 // The whole pattern is reachable only when all its alternatives are.
671669 SubPatSet :: Seq { subpats } => subpats. values ( ) . all ( |sub_set| sub_set. is_full ( ) ) ,
672670 // 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 ( ) )
675673 }
676674 }
677675 }
@@ -726,7 +724,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
726724 /// whole pattern is unreachable) we return `None`.
727725 fn list_unreachable_spans ( & self ) -> Option < Vec < Span > > {
728726 /// 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 > ) {
730728 match set {
731729 SubPatSet :: Empty => bug ! ( ) ,
732730 SubPatSet :: Full => { }
@@ -735,13 +733,12 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
735733 fill_spans ( sub_set, spans) ;
736734 }
737735 }
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 ( ) {
741738 let sub_set = subpats. get ( & i) . unwrap_or ( & SubPatSet :: Empty ) ;
742739 if sub_set. is_empty ( ) {
743740 // Found an unreachable subpattern.
744- spans. push ( expanded [ i ] . span ) ;
741+ spans. push ( * span) ;
745742 } else {
746743 fill_spans ( sub_set, spans) ;
747744 }
@@ -806,7 +803,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
806803 /// Here `None` would return the full set and `Some(true | false)` would return the set
807804 /// containing `false`. After `unsplit_or_pat`, we want the set to contain `None` and `false`.
808805 /// 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 {
810807 use SubPatSet :: * ;
811808 if self . is_empty ( ) {
812809 return Empty ;
@@ -822,7 +819,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
822819 } ;
823820 let mut subpats_first_col = FxHashMap :: default ( ) ;
824821 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 } ;
826823
827824 let mut subpats = match self {
828825 Full => FxHashMap :: default ( ) ,
@@ -842,19 +839,19 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
842839/// witnesses of non-exhaustiveness when there are any.
843840/// Which variant to use is dictated by `ArmType`.
844841#[ derive( Clone , Debug ) ]
845- enum Usefulness < ' p , ' tcx > {
842+ enum Usefulness < ' tcx > {
846843 /// Carries a set of subpatterns that have been found to be reachable. If empty, this indicates
847844 /// the whole pattern is unreachable. If not, this indicates that the pattern is reachable but
848845 /// that some sub-patterns may be unreachable (due to or-patterns). In the absence of
849846 /// or-patterns this will always be either `Empty` (the whole pattern is unreachable) or `Full`
850847 /// (the whole pattern is reachable).
851- NoWitnesses ( SubPatSet < ' p , ' tcx > ) ,
848+ NoWitnesses ( SubPatSet ) ,
852849 /// Carries a list of witnesses of non-exhaustiveness. If empty, indicates that the whole
853850 /// pattern is unreachable.
854851 WithWitnesses ( Vec < Witness < ' tcx > > ) ,
855852}
856853
857- impl < ' p , ' tcx > Usefulness < ' p , ' tcx > {
854+ impl < ' tcx > Usefulness < ' tcx > {
858855 fn new_useful ( preference : ArmType ) -> Self {
859856 match preference {
860857 FakeExtraWildcard => WithWitnesses ( vec ! [ Witness ( vec![ ] ) ] ) ,
@@ -889,17 +886,17 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
889886
890887 /// After calculating the usefulness for a branch of an or-pattern, call this to make this
891888 /// 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 {
893890 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 ) ) ,
895892 WithWitnesses ( _) => bug ! ( ) ,
896893 }
897894 }
898895
899896 /// After calculating usefulness after a specialization, call this to reconstruct a usefulness
900897 /// that makes sense for the matrix pre-specialization. This new usefulness can then be merged
901898 /// with the results of specializing with the other constructors.
902- fn apply_constructor (
899+ fn apply_constructor < ' p > (
903900 self ,
904901 pcx : PatCtxt < ' _ , ' p , ' tcx > ,
905902 matrix : & Matrix < ' p , ' tcx > , // used to compute missing ctors
@@ -1099,7 +1096,7 @@ fn is_useful<'p, 'tcx>(
10991096 hir_id : HirId ,
11001097 is_under_guard : bool ,
11011098 is_top_level : bool ,
1102- ) -> Usefulness < ' p , ' tcx > {
1099+ ) -> Usefulness < ' tcx > {
11031100 debug ! ( "matrix,v={:?}{:?}" , matrix, v) ;
11041101 let Matrix { patterns : rows, .. } = matrix;
11051102
@@ -1129,15 +1126,14 @@ fn is_useful<'p, 'tcx>(
11291126 let mut ret = Usefulness :: new_not_useful ( witness_preference) ;
11301127 if is_or_pat ( v. head ( ) ) {
11311128 debug ! ( "expanding or-pattern" ) ;
1132- let v_head = v. head ( ) ;
11331129 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 ( ) ;
11351131 // We try each or-pattern branch in turn.
11361132 let mut matrix = matrix. clone ( ) ;
11371133 for ( i, v) in vs. into_iter ( ) . enumerate ( ) {
11381134 let usefulness =
11391135 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 ( ) ) ;
11411137 ret. extend ( usefulness) ;
11421138 // If pattern has a guard don't add it to the matrix.
11431139 if !is_under_guard {
0 commit comments