@@ -21,27 +21,30 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
21
21
} ;
22
22
23
23
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 ( ) ;
25
28
26
29
// 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
28
31
. iter ( )
29
32
. enumerate ( )
30
33
. map ( |( i, pat) | {
31
- resolved_pats [ i + 1 ..]
34
+ normalized_pats [ i + 1 ..]
32
35
. iter ( )
33
36
. enumerate ( )
34
37
. 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 ( ) )
36
39
} )
37
40
. collect ( ) ;
38
41
39
42
// 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
41
44
. iter ( )
42
45
. enumerate ( )
43
46
. map ( |( i, pat) | {
44
- resolved_pats [ ..i]
47
+ normalized_pats [ ..i]
45
48
. iter ( )
46
49
. enumerate ( )
47
50
. rev ( )
@@ -133,18 +136,18 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
133
136
}
134
137
135
138
#[ derive( Clone , Copy ) ]
136
- enum ResolvedPat < ' hir , ' arena > {
139
+ enum NormalizedPat < ' a > {
137
140
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 ] ) ,
141
144
Path ( Option < DefId > ) ,
142
145
LitStr ( Symbol ) ,
143
- LitBytes ( & ' hir [ u8 ] ) ,
146
+ LitBytes ( & ' a [ u8 ] ) ,
144
147
LitInt ( u128 ) ,
145
148
LitBool ( bool ) ,
146
149
Range ( PatRange ) ,
147
- Slice ( & ' arena [ Self ] , & ' arena [ Self ] , bool ) ,
150
+ Slice ( & ' a [ Self ] , Option < & ' a [ Self ] > ) ,
148
151
}
149
152
150
153
#[ derive( Clone , Copy ) ]
@@ -183,9 +186,9 @@ impl PatRange {
183
186
}
184
187
185
188
#[ allow( clippy:: similar_names) ]
186
- impl < ' hir , ' arena > ResolvedPat < ' hir , ' arena > {
189
+ impl < ' a > NormalizedPat < ' a > {
187
190
#[ 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 {
189
192
match pat. kind {
190
193
PatKind :: Wild | PatKind :: Binding ( .., None ) => Self :: Wild ,
191
194
PatKind :: Binding ( .., Some ( pat) ) | PatKind :: Box ( pat) | PatKind :: Ref ( pat, _) => {
@@ -284,8 +287,7 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
284
287
} ,
285
288
PatKind :: Slice ( front, wild_pat, back) => Self :: Slice (
286
289
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) ) ) ) ,
289
291
) ,
290
292
}
291
293
}
@@ -345,6 +347,25 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
345
347
( Self :: LitBool ( x) , Self :: LitBool ( y) ) => x == y,
346
348
( Self :: Range ( ref x) , Self :: Range ( ref y) ) => x. overlaps ( y) ,
347
349
( 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) ) ,
348
369
349
370
// Todo: Lit* with Path, Range with Path, LitBytes with Slice, Slice with Slice
350
371
_ => true ,
0 commit comments