@@ -34,31 +34,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
34
34
] ,
35
35
MatchSource :: Normal ,
36
36
) = if_expr. kind
37
- && let Some ( ( pat_binding, can_use_shorthand) ) = get_pat_binding ( cx, scrutinee, outer_arm)
38
37
{
39
38
emit_redundant_guards (
40
39
cx,
41
40
outer_arm,
42
41
if_expr. span ,
43
- pat_binding,
44
- can_use_shorthand,
42
+ scrutinee,
45
43
arm. pat . span ,
46
44
arm. guard ,
47
45
& mut app,
48
46
) ;
49
47
}
50
48
// `Some(x) if let Some(2) = x`
51
- else if let Guard :: IfLet ( let_expr) = guard
52
- && let pat = let_expr. pat
53
- && let Some ( ( pat_binding, can_use_shorthand) ) = get_pat_binding ( cx, let_expr. init , outer_arm)
54
- {
49
+ else if let Guard :: IfLet ( let_expr) = guard {
55
50
emit_redundant_guards (
56
51
cx,
57
52
outer_arm,
58
53
let_expr. span ,
59
- pat_binding,
60
- can_use_shorthand,
61
- pat. span ,
54
+ let_expr. init ,
55
+ let_expr. pat . span ,
62
56
None ,
63
57
& mut app,
64
58
) ;
@@ -67,7 +61,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
67
61
else if let Guard :: If ( if_expr) = guard
68
62
&& let ExprKind :: Binary ( bin_op, local, pat) = if_expr. kind
69
63
&& matches ! ( bin_op. node, BinOpKind :: Eq )
70
- && let Some ( ( pat_binding, can_use_shorthand) ) = get_pat_binding ( cx, local, outer_arm)
71
64
&& expr_can_be_pat ( cx, pat)
72
65
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
73
66
// possible (currently) in a pattern. In some cases, you can use something like
@@ -81,8 +74,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
81
74
cx,
82
75
outer_arm,
83
76
if_expr. span ,
84
- pat_binding,
85
- can_use_shorthand,
77
+ local,
86
78
pat. span ,
87
79
None ,
88
80
& mut app,
@@ -94,12 +86,18 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
94
86
fn get_pat_binding < ' tcx > ( cx : & LateContext < ' tcx > , guard_expr : & Expr < ' _ > , outer_arm : & Arm < ' tcx > ) -> Option < ( Span , bool ) > {
95
87
if let Some ( local) = path_to_local ( guard_expr) && !is_local_used ( cx, outer_arm. body , local) {
96
88
let mut span = None ;
97
- // FIXME: hir_id == local is only true for the first or, this will always be false
98
89
let mut multiple_bindings = false ;
99
- outer_arm. pat . each_binding ( |_, hir_id, binding_span, _| {
100
- if hir_id == local && span. replace ( binding_span) . is_some ( ) {
90
+ // `each_binding` gives the `HirId` of the `Pat` itself, not the binding
91
+ outer_arm. pat . walk ( |pat| {
92
+ if let PatKind :: Binding ( _, hir_id, _, _) = pat. kind
93
+ && hir_id == local
94
+ && span. replace ( pat. span ) . is_some ( )
95
+ {
101
96
multiple_bindings = true ;
97
+ return false ;
102
98
}
99
+
100
+ true
103
101
} ) ;
104
102
105
103
if !multiple_bindings {
@@ -115,28 +113,19 @@ fn get_pat_binding<'tcx>(cx: &LateContext<'tcx>, guard_expr: &Expr<'_>, outer_ar
115
113
None
116
114
}
117
115
118
- fn get_guard ( cx : & LateContext < ' _ > , guard : Option < Guard < ' _ > > , app : & mut Applicability ) -> String {
119
- guard. map_or_else ( String :: new, |guard| {
120
- let ( prefix, span) = match guard {
121
- Guard :: If ( e) => ( "if" , e. span ) ,
122
- Guard :: IfLet ( l) => ( "if let" , l. span ) ,
123
- } ;
124
-
125
- format ! ( " {prefix} {}" , snippet_with_applicability( cx, span, "<guard>" , app) )
126
- } )
127
- }
128
-
129
- #[ expect( clippy:: too_many_arguments) ]
130
- fn emit_redundant_guards (
131
- cx : & LateContext < ' _ > ,
132
- outer_arm : & Arm < ' _ > ,
116
+ fn emit_redundant_guards < ' tcx > (
117
+ cx : & LateContext < ' tcx > ,
118
+ outer_arm : & Arm < ' tcx > ,
133
119
guard_span : Span ,
134
- pat_binding : Span ,
135
- can_use_shorthand : bool ,
120
+ local : & Expr < ' _ > ,
136
121
pat_span : Span ,
137
122
inner_guard : Option < Guard < ' _ > > ,
138
123
app : & mut Applicability ,
139
124
) {
125
+ let Some ( ( pat_binding, can_use_shorthand) ) = get_pat_binding ( cx, local, outer_arm) else {
126
+ return ;
127
+ } ;
128
+
140
129
span_lint_and_then (
141
130
cx,
142
131
REDUNDANT_GUARDS ,
@@ -154,7 +143,14 @@ fn emit_redundant_guards(
154
143
} ,
155
144
(
156
145
guard_span. source_callsite( ) . with_lo( outer_arm. pat. span. hi( ) ) ,
157
- get_guard( cx, inner_guard, app) ,
146
+ inner_guard. map_or_else( String :: new, |guard| {
147
+ let ( prefix, span) = match guard {
148
+ Guard :: If ( e) => ( "if" , e. span) ,
149
+ Guard :: IfLet ( l) => ( "if let" , l. span) ,
150
+ } ;
151
+
152
+ format!( " {prefix} {}" , snippet_with_applicability( cx, span, "<guard>" , app) )
153
+ } ) ,
158
154
) ,
159
155
] ,
160
156
* app,
0 commit comments