1
- use clippy_utils:: diagnostics:: span_lint_and_note;
2
- use clippy_utils:: { eq_expr_value, in_macro, search_same, SpanlessEq , SpanlessHash } ;
3
- use clippy_utils:: { get_parent_expr, if_sequence} ;
4
- use rustc_hir:: { Block , Expr , ExprKind } ;
1
+ use crate :: utils:: { both, count_eq, eq_expr_value, in_macro, search_same, SpanlessEq , SpanlessHash } ;
2
+ use crate :: utils:: {
3
+ first_line_of_span, get_parent_expr, higher, if_sequence, indent_of, parent_node_is_if_expr, reindent_multiline,
4
+ snippet, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
5
+ } ;
6
+ use rustc_data_structures:: fx:: FxHashSet ;
7
+ use rustc_errors:: Applicability ;
8
+ use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
9
+ use rustc_hir:: { Block , Expr , HirId } ;
5
10
use rustc_lint:: { LateContext , LateLintPass } ;
6
11
use rustc_middle:: hir:: map:: Map ;
7
12
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -136,7 +141,7 @@ declare_clippy_lint! {
136
141
/// };
137
142
/// ```
138
143
pub SHARED_CODE_IN_IF_BLOCKS ,
139
- pedantic ,
144
+ nursery ,
140
145
"`if` statement with shared code in all blocks"
141
146
}
142
147
@@ -180,7 +185,7 @@ fn lint_same_then_else<'tcx>(
180
185
) {
181
186
// We only lint ifs with multiple blocks
182
187
// TODO xFrednet 2021-01-01: Check if it's an else if block
183
- if blocks. len ( ) < 2 {
188
+ if blocks. len ( ) < 2 || parent_node_is_if_expr ( expr , cx ) {
184
189
return ;
185
190
}
186
191
@@ -190,7 +195,7 @@ fn lint_same_then_else<'tcx>(
190
195
let mut start_eq = usize:: MAX ;
191
196
let mut end_eq = usize:: MAX ;
192
197
let mut expr_eq = true ;
193
- for ( index , win) in blocks. windows ( 2 ) . enumerate ( ) {
198
+ for win in blocks. windows ( 2 ) {
194
199
let l_stmts = win[ 0 ] . stmts ;
195
200
let r_stmts = win[ 1 ] . stmts ;
196
201
@@ -202,9 +207,7 @@ fn lint_same_then_else<'tcx>(
202
207
let block_expr_eq = both ( & win[ 0 ] . expr , & win[ 1 ] . expr , |l, r| evaluator. eq_expr ( l, r) ) ;
203
208
204
209
// IF_SAME_THEN_ELSE
205
- // We only lint the first two blocks (index == 0). Further blocks will be linted when that if
206
- // statement is checked
207
- if index == 0 && block_expr_eq && l_stmts. len ( ) == r_stmts. len ( ) && l_stmts. len ( ) == current_start_eq {
210
+ if block_expr_eq && l_stmts. len ( ) == r_stmts. len ( ) && l_stmts. len ( ) == current_start_eq {
208
211
span_lint_and_note (
209
212
cx,
210
213
IF_SAME_THEN_ELSE ,
@@ -215,16 +218,24 @@ fn lint_same_then_else<'tcx>(
215
218
) ;
216
219
217
220
return ;
221
+ } else {
222
+ println ! (
223
+ "{:?}\n - expr_eq: {:10}, l_stmts.len(): {:10}, r_stmts.len(): {:10}" ,
224
+ win[ 0 ] . span,
225
+ block_expr_eq,
226
+ l_stmts. len( ) ,
227
+ r_stmts. len( )
228
+ )
218
229
}
219
230
220
231
start_eq = start_eq. min ( current_start_eq) ;
221
232
end_eq = end_eq. min ( current_end_eq) ;
222
233
expr_eq &= block_expr_eq;
234
+ }
223
235
224
- // We can return if the eq count is 0 from both sides or if it has no unconditional else case
225
- if !has_unconditional_else || ( start_eq == 0 && end_eq == 0 && ( has_expr && !expr_eq) ) {
226
- return ;
227
- }
236
+ // SHARED_CODE_IN_IF_BLOCKS prerequisites
237
+ if !has_unconditional_else || ( start_eq == 0 && end_eq == 0 && ( has_expr && !expr_eq) ) {
238
+ return ;
228
239
}
229
240
230
241
if has_expr && !expr_eq {
@@ -275,11 +286,14 @@ fn lint_same_then_else<'tcx>(
275
286
end_eq -= moved_start;
276
287
}
277
288
278
- let mut end_linable = true ;
279
- if let Some ( expr) = block. expr {
289
+ let end_linable = if let Some ( expr) = block. expr {
280
290
intravisit:: walk_expr ( & mut walker, expr) ;
281
- end_linable = walker. uses . iter ( ) . any ( |x| !block_defs. contains ( x) ) ;
282
- }
291
+ walker. uses . iter ( ) . any ( |x| !block_defs. contains ( x) )
292
+ } else if end_eq == 0 {
293
+ false
294
+ } else {
295
+ true
296
+ } ;
283
297
284
298
emit_shared_code_in_if_blocks_lint ( cx, start_eq, end_eq, end_linable, blocks, expr) ;
285
299
}
@@ -351,7 +365,7 @@ fn emit_shared_code_in_if_blocks_lint(
351
365
SHARED_CODE_IN_IF_BLOCKS ,
352
366
* span,
353
367
"All code blocks contain the same code" ,
354
- "Consider moving the code out like this" ,
368
+ "Consider moving the statements out like this" ,
355
369
sugg. clone ( ) ,
356
370
Applicability :: Unspecified ,
357
371
) ;
0 commit comments