@@ -21,27 +21,30 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
2121 } ;
2222
2323 let arena = DroplessArena :: default ( ) ;
24- let resolved_pats: Vec < _ > = arms. iter ( ) . map ( |a| ResolvedPat :: from_pat ( cx, & arena, a. pat ) ) . collect ( ) ;
24+ let normalized_pats: Vec < _ > = arms
25+ . iter ( )
26+ . map ( |a| NormalizedPat :: from_pat ( cx, & arena, a. pat ) )
27+ . collect ( ) ;
2528
2629 // The furthast forwards a pattern can move without semantic changes
27- let forwards_blocking_idxs: Vec < _ > = resolved_pats
30+ let forwards_blocking_idxs: Vec < _ > = normalized_pats
2831 . iter ( )
2932 . enumerate ( )
3033 . map ( |( i, pat) | {
31- resolved_pats [ i + 1 ..]
34+ normalized_pats [ i + 1 ..]
3235 . iter ( )
3336 . enumerate ( )
3437 . find_map ( |( j, other) | pat. can_also_match ( other) . then ( || i + 1 + j) )
35- . unwrap_or ( resolved_pats . len ( ) )
38+ . unwrap_or ( normalized_pats . len ( ) )
3639 } )
3740 . collect ( ) ;
3841
3942 // The furthast backwards a pattern can move without semantic changes
40- let backwards_blocking_idxs: Vec < _ > = resolved_pats
43+ let backwards_blocking_idxs: Vec < _ > = normalized_pats
4144 . iter ( )
4245 . enumerate ( )
4346 . map ( |( i, pat) | {
44- resolved_pats [ ..i]
47+ normalized_pats [ ..i]
4548 . iter ( )
4649 . enumerate ( )
4750 . rev ( )
@@ -133,18 +136,18 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
133136}
134137
135138#[ derive( Clone , Copy ) ]
136- enum ResolvedPat < ' hir , ' arena > {
139+ enum NormalizedPat < ' a > {
137140 Wild ,
138- Struct ( Option < DefId > , & ' arena [ ( Symbol , Self ) ] ) ,
139- Tuple ( Option < DefId > , & ' arena [ Self ] ) ,
140- Or ( & ' arena [ Self ] ) ,
141+ Struct ( Option < DefId > , & ' a [ ( Symbol , Self ) ] ) ,
142+ Tuple ( Option < DefId > , & ' a [ Self ] ) ,
143+ Or ( & ' a [ Self ] ) ,
141144 Path ( Option < DefId > ) ,
142145 LitStr ( Symbol ) ,
143- LitBytes ( & ' hir [ u8 ] ) ,
146+ LitBytes ( & ' a [ u8 ] ) ,
144147 LitInt ( u128 ) ,
145148 LitBool ( bool ) ,
146149 Range ( PatRange ) ,
147- Slice ( & ' arena [ Self ] , & ' arena [ Self ] , bool ) ,
150+ Slice ( & ' a [ Self ] , Option < & ' a [ Self ] > ) ,
148151}
149152
150153#[ derive( Clone , Copy ) ]
@@ -183,9 +186,9 @@ impl PatRange {
183186}
184187
185188#[ allow( clippy:: similar_names) ]
186- impl < ' hir , ' arena > ResolvedPat < ' hir , ' arena > {
189+ impl < ' a > NormalizedPat < ' a > {
187190 #[ allow( clippy:: too_many_lines) ]
188- fn from_pat ( cx : & LateContext < ' _ > , arena : & ' arena DroplessArena , pat : & ' hir Pat < ' _ > ) -> Self {
191+ fn from_pat ( cx : & LateContext < ' _ > , arena : & ' a DroplessArena , pat : & ' a Pat < ' _ > ) -> Self {
189192 match pat. kind {
190193 PatKind :: Wild | PatKind :: Binding ( .., None ) => Self :: Wild ,
191194 PatKind :: Binding ( .., Some ( pat) ) | PatKind :: Box ( pat) | PatKind :: Ref ( pat, _) => {
@@ -284,8 +287,7 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
284287 } ,
285288 PatKind :: Slice ( front, wild_pat, back) => Self :: Slice (
286289 arena. alloc_from_iter ( front. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ,
287- arena. alloc_from_iter ( back. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ,
288- wild_pat. is_some ( ) ,
290+ wild_pat. map ( |_| & * arena. alloc_from_iter ( back. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ) ,
289291 ) ,
290292 }
291293 }
@@ -345,6 +347,25 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
345347 ( Self :: LitBool ( x) , Self :: LitBool ( y) ) => x == y,
346348 ( Self :: Range ( ref x) , Self :: Range ( ref y) ) => x. overlaps ( y) ,
347349 ( Self :: Range ( ref range) , Self :: LitInt ( x) ) | ( Self :: LitInt ( x) , Self :: Range ( ref range) ) => range. contains ( x) ,
350+ ( Self :: Slice ( lpats, None ) , Self :: Slice ( rpats, None ) ) => {
351+ lpats. len ( ) == rpats. len ( ) && lpats. iter ( ) . zip ( rpats. iter ( ) ) . all ( |( x, y) | x. can_also_match ( y) )
352+ } ,
353+ ( Self :: Slice ( pats, None ) , Self :: Slice ( front, Some ( back) ) )
354+ | ( Self :: Slice ( front, Some ( back) ) , Self :: Slice ( pats, None ) ) => {
355+ if pats. len ( ) < front. len ( ) + back. len ( ) {
356+ return false ;
357+ }
358+ pats[ ..front. len ( ) ]
359+ . iter ( )
360+ . zip ( front. iter ( ) )
361+ . chain ( pats[ pats. len ( ) - back. len ( ) ..] . iter ( ) . zip ( back. iter ( ) ) )
362+ . all ( |( x, y) | x. can_also_match ( y) )
363+ } ,
364+ ( Self :: Slice ( lfront, Some ( lback) ) , Self :: Slice ( rfront, Some ( rback) ) ) => lfront
365+ . iter ( )
366+ . zip ( rfront. iter ( ) )
367+ . chain ( lback. iter ( ) . rev ( ) . zip ( rback. iter ( ) . rev ( ) ) )
368+ . all ( |( x, y) | x. can_also_match ( y) ) ,
348369
349370 // Todo: Lit* with Path, Range with Path, LitBytes with Slice, Slice with Slice
350371 _ => true ,
0 commit comments