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