11use clippy_utils:: diagnostics:: span_lint_and_then;
22use clippy_utils:: source:: SpanRangeExt ;
3- use clippy_utils:: { SpanlessEq , SpanlessHash , fulfill_or_allowed , is_lint_allowed, path_to_local, search_same} ;
3+ use clippy_utils:: { SpanlessEq , fulfill_or_allowed , hash_expr , is_lint_allowed, path_to_local, search_same} ;
44use core:: cmp:: Ordering ;
55use core:: { iter, slice} ;
66use itertools:: Itertools ;
@@ -18,11 +18,7 @@ use super::MATCH_SAME_ARMS;
1818
1919#[ expect( clippy:: too_many_lines) ]
2020pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , arms : & ' tcx [ Arm < ' _ > ] ) {
21- let hash = |& ( _, arm) : & ( usize , & Arm < ' _ > ) | -> u64 {
22- let mut h = SpanlessHash :: new ( cx) ;
23- h. hash_expr ( arm. body ) ;
24- h. finish ( )
25- } ;
21+ let hash = |& ( _, arm) : & ( _ , & Arm < ' _ > ) | hash_expr ( cx, arm. body ) ;
2622
2723 let arena = DroplessArena :: default ( ) ;
2824 let normalized_pats: Vec < _ > = arms
@@ -35,9 +31,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
3531 . iter ( )
3632 . enumerate ( )
3733 . map ( |( i, pat) | {
38- normalized_pats[ i + 1 ..]
39- . iter ( )
40- . enumerate ( )
34+ ( normalized_pats[ i + 1 ..] . iter ( ) . enumerate ( ) )
4135 . find_map ( |( j, other) | pat. has_overlapping_values ( other) . then_some ( i + 1 + j) )
4236 . unwrap_or ( normalized_pats. len ( ) )
4337 } )
@@ -48,16 +42,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
4842 . iter ( )
4943 . enumerate ( )
5044 . map ( |( i, pat) | {
51- normalized_pats[ ..i]
52- . iter ( )
53- . enumerate ( )
54- . rev ( )
55- . zip ( forwards_blocking_idxs[ ..i] . iter ( ) . copied ( ) . rev ( ) )
56- . skip_while ( |& ( _, forward_block) | forward_block > i)
57- . find_map ( |( ( j, other) , forward_block) | {
58- ( forward_block == i || pat. has_overlapping_values ( other) ) . then_some ( j)
59- } )
60- . unwrap_or ( 0 )
45+ iter:: zip (
46+ normalized_pats[ ..i] . iter ( ) . enumerate ( ) . rev ( ) ,
47+ forwards_blocking_idxs[ ..i] . iter ( ) . copied ( ) . rev ( ) ,
48+ )
49+ . skip_while ( |& ( _, forward_block) | forward_block > i)
50+ . find_map ( |( ( j, other) , forward_block) | {
51+ ( forward_block == i || pat. has_overlapping_values ( other) ) . then_some ( j)
52+ } )
53+ . unwrap_or ( 0 )
6154 } )
6255 . collect ( ) ;
6356
@@ -158,12 +151,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
158151 . map ( |( _, arm) | arm. pat . span . get_source_text ( cx) )
159152 . collect :: < Option < Vec < _ > > > ( )
160153 {
161- let mut suggs = src
154+ let suggs = src
162155 . iter ( )
163156 . map ( |( _, arm) | ( adjusted_arm_span ( cx, arm. span ) , String :: new ( ) ) )
157+ . chain ( [ ( dest. pat . span , pat_snippets. iter ( ) . join ( " | " ) ) ] )
164158 . collect_vec ( ) ;
165159
166- suggs. push ( ( dest. pat . span , pat_snippets. iter ( ) . join ( " | " ) ) ) ;
167160 diag. multipart_suggestion_verbose (
168161 "otherwise merge the patterns into a single arm" ,
169162 suggs,
@@ -396,10 +389,7 @@ impl<'a> NormalizedPat<'a> {
396389 if lpath != rpath {
397390 return false ;
398391 }
399- lpats
400- . iter ( )
401- . zip ( rpats. iter ( ) )
402- . all ( |( lpat, rpat) | lpat. has_overlapping_values ( rpat) )
392+ iter:: zip ( lpats, rpats) . all ( |( lpat, rpat) | lpat. has_overlapping_values ( rpat) )
403393 } ,
404394 ( Self :: Path ( x) , Self :: Path ( y) ) => x == y,
405395 ( Self :: LitStr ( x) , Self :: LitStr ( y) ) => x == y,
@@ -409,7 +399,7 @@ impl<'a> NormalizedPat<'a> {
409399 ( Self :: Range ( ref x) , Self :: Range ( ref y) ) => x. overlaps ( y) ,
410400 ( Self :: Range ( ref range) , Self :: LitInt ( x) ) | ( Self :: LitInt ( x) , Self :: Range ( ref range) ) => range. contains ( x) ,
411401 ( Self :: Slice ( lpats, None ) , Self :: Slice ( rpats, None ) ) => {
412- lpats. len ( ) == rpats. len ( ) && lpats . iter ( ) . zip ( rpats. iter ( ) ) . all ( |( x, y) | x. has_overlapping_values ( y) )
402+ lpats. len ( ) == rpats. len ( ) && iter:: zip ( lpats , rpats) . all ( |( x, y) | x. has_overlapping_values ( y) )
413403 } ,
414404 ( Self :: Slice ( pats, None ) , Self :: Slice ( front, Some ( back) ) )
415405 | ( Self :: Slice ( front, Some ( back) ) , Self :: Slice ( pats, None ) ) => {
@@ -418,16 +408,12 @@ impl<'a> NormalizedPat<'a> {
418408 if pats. len ( ) < front. len ( ) + back. len ( ) {
419409 return false ;
420410 }
421- pats[ ..front. len ( ) ]
422- . iter ( )
423- . zip ( front. iter ( ) )
424- . chain ( pats[ pats. len ( ) - back. len ( ) ..] . iter ( ) . zip ( back. iter ( ) ) )
411+ iter:: zip ( & pats[ ..front. len ( ) ] , front)
412+ . chain ( iter:: zip ( & pats[ pats. len ( ) - back. len ( ) ..] , back) )
425413 . all ( |( x, y) | x. has_overlapping_values ( y) )
426414 } ,
427- ( Self :: Slice ( lfront, Some ( lback) ) , Self :: Slice ( rfront, Some ( rback) ) ) => lfront
428- . iter ( )
429- . zip ( rfront. iter ( ) )
430- . chain ( lback. iter ( ) . rev ( ) . zip ( rback. iter ( ) . rev ( ) ) )
415+ ( Self :: Slice ( lfront, Some ( lback) ) , Self :: Slice ( rfront, Some ( rback) ) ) => iter:: zip ( lfront, rfront)
416+ . chain ( iter:: zip ( lback. iter ( ) . rev ( ) , rback. iter ( ) . rev ( ) ) )
431417 . all ( |( x, y) | x. has_overlapping_values ( y) ) ,
432418
433419 // Enums can mix unit variants with tuple/struct variants. These can never overlap.
0 commit comments