@@ -2245,18 +2245,18 @@ fn test_overlapping() {
2245
2245
}
2246
2246
2247
2247
#[ derive( Clone , Copy ) ]
2248
- enum ResolvedPat < ' hir , ' arena > {
2248
+ enum NormalizedPat < ' a > {
2249
2249
Wild ,
2250
- Struct ( Option < DefId > , & ' arena [ ( Symbol , Self ) ] ) ,
2251
- Tuple ( Option < DefId > , & ' arena [ Self ] ) ,
2252
- Or ( & ' arena [ Self ] ) ,
2250
+ Struct ( Option < DefId > , & ' a [ ( Symbol , Self ) ] ) ,
2251
+ Tuple ( Option < DefId > , & ' a [ Self ] ) ,
2252
+ Or ( & ' a [ Self ] ) ,
2253
2253
Path ( Option < DefId > ) ,
2254
2254
LitStr ( Symbol ) ,
2255
- LitBytes ( & ' hir [ u8 ] ) ,
2255
+ LitBytes ( & ' a [ u8 ] ) ,
2256
2256
LitInt ( u128 ) ,
2257
2257
LitBool ( bool ) ,
2258
2258
Range ( PatRange ) ,
2259
- Slice ( & ' arena [ Self ] , & ' arena [ Self ] , bool ) ,
2259
+ Slice ( & ' a [ Self ] , Option < & ' a [ Self ] > ) ,
2260
2260
}
2261
2261
2262
2262
#[ derive( Clone , Copy ) ]
@@ -2295,9 +2295,9 @@ impl PatRange {
2295
2295
}
2296
2296
2297
2297
#[ allow( clippy:: similar_names) ]
2298
- impl < ' hir , ' arena > ResolvedPat < ' hir , ' arena > {
2298
+ impl < ' a > NormalizedPat < ' a > {
2299
2299
#[ allow( clippy:: too_many_lines) ]
2300
- fn from_pat ( cx : & LateContext < ' _ > , arena : & ' arena DroplessArena , pat : & ' hir Pat < ' _ > ) -> Self {
2300
+ fn from_pat ( cx : & LateContext < ' _ > , arena : & ' a DroplessArena , pat : & ' a Pat < ' _ > ) -> Self {
2301
2301
match pat. kind {
2302
2302
PatKind :: Wild | PatKind :: Binding ( .., None ) => Self :: Wild ,
2303
2303
PatKind :: Binding ( .., Some ( pat) ) | PatKind :: Box ( pat) | PatKind :: Ref ( pat, _) => {
@@ -2396,8 +2396,7 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
2396
2396
} ,
2397
2397
PatKind :: Slice ( front, wild_pat, back) => Self :: Slice (
2398
2398
arena. alloc_from_iter ( front. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ,
2399
- arena. alloc_from_iter ( back. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ,
2400
- wild_pat. is_some ( ) ,
2399
+ wild_pat. map ( |_| & * arena. alloc_from_iter ( back. iter ( ) . map ( |pat| Self :: from_pat ( cx, arena, pat) ) ) ) ,
2401
2400
) ,
2402
2401
}
2403
2402
}
@@ -2457,6 +2456,25 @@ impl<'hir, 'arena> ResolvedPat<'hir, 'arena> {
2457
2456
( Self :: LitBool ( x) , Self :: LitBool ( y) ) => x == y,
2458
2457
( Self :: Range ( ref x) , Self :: Range ( ref y) ) => x. overlaps ( y) ,
2459
2458
( Self :: Range ( ref range) , Self :: LitInt ( x) ) | ( Self :: LitInt ( x) , Self :: Range ( ref range) ) => range. contains ( x) ,
2459
+ ( Self :: Slice ( lpats, None ) , Self :: Slice ( rpats, None ) ) => {
2460
+ lpats. len ( ) == rpats. len ( ) && lpats. iter ( ) . zip ( rpats. iter ( ) ) . all ( |( x, y) | x. can_also_match ( y) )
2461
+ } ,
2462
+ ( Self :: Slice ( pats, None ) , Self :: Slice ( front, Some ( back) ) )
2463
+ | ( Self :: Slice ( front, Some ( back) ) , Self :: Slice ( pats, None ) ) => {
2464
+ if pats. len ( ) < front. len ( ) + back. len ( ) {
2465
+ return false ;
2466
+ }
2467
+ pats[ ..front. len ( ) ]
2468
+ . iter ( )
2469
+ . zip ( front. iter ( ) )
2470
+ . chain ( pats[ pats. len ( ) - back. len ( ) ..] . iter ( ) . zip ( back. iter ( ) ) )
2471
+ . all ( |( x, y) | x. can_also_match ( y) )
2472
+ } ,
2473
+ ( Self :: Slice ( lfront, Some ( lback) ) , Self :: Slice ( rfront, Some ( rback) ) ) => lfront
2474
+ . iter ( )
2475
+ . zip ( rfront. iter ( ) )
2476
+ . chain ( lback. iter ( ) . rev ( ) . zip ( rback. iter ( ) . rev ( ) ) )
2477
+ . all ( |( x, y) | x. can_also_match ( y) ) ,
2460
2478
2461
2479
// Todo: Lit* with Path, Range with Path, LitBytes with Slice, Slice with Slice
2462
2480
_ => true ,
@@ -2474,27 +2492,30 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) {
2474
2492
} ;
2475
2493
2476
2494
let arena = DroplessArena :: default ( ) ;
2477
- let resolved_pats: Vec < _ > = arms. iter ( ) . map ( |a| ResolvedPat :: from_pat ( cx, & arena, a. pat ) ) . collect ( ) ;
2495
+ let normalized_pats: Vec < _ > = arms
2496
+ . iter ( )
2497
+ . map ( |a| NormalizedPat :: from_pat ( cx, & arena, a. pat ) )
2498
+ . collect ( ) ;
2478
2499
2479
2500
// The furthast forwards a pattern can move without semantic changes
2480
- let forwards_blocking_idxs: Vec < _ > = resolved_pats
2501
+ let forwards_blocking_idxs: Vec < _ > = normalized_pats
2481
2502
. iter ( )
2482
2503
. enumerate ( )
2483
2504
. map ( |( i, pat) | {
2484
- resolved_pats [ i + 1 ..]
2505
+ normalized_pats [ i + 1 ..]
2485
2506
. iter ( )
2486
2507
. enumerate ( )
2487
2508
. find_map ( |( j, other) | pat. can_also_match ( other) . then ( || i + 1 + j) )
2488
- . unwrap_or ( resolved_pats . len ( ) )
2509
+ . unwrap_or ( normalized_pats . len ( ) )
2489
2510
} )
2490
2511
. collect ( ) ;
2491
2512
2492
2513
// The furthast backwards a pattern can move without semantic changes
2493
- let backwards_blocking_idxs: Vec < _ > = resolved_pats
2514
+ let backwards_blocking_idxs: Vec < _ > = normalized_pats
2494
2515
. iter ( )
2495
2516
. enumerate ( )
2496
2517
. map ( |( i, pat) | {
2497
- resolved_pats [ ..i]
2518
+ normalized_pats [ ..i]
2498
2519
. iter ( )
2499
2520
. enumerate ( )
2500
2521
. rev ( )
0 commit comments