11use crate :: utils:: { both, count_eq, eq_expr_value, in_macro, search_same, SpanlessEq , SpanlessHash } ;
22use 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,
3+ first_line_of_span, get_parent_expr, if_sequence, indent_of, parent_node_is_if_expr, reindent_multiline, snippet ,
4+ snippet_opt , span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
55} ;
66use rustc_data_structures:: fx:: FxHashSet ;
77use rustc_errors:: Applicability ;
88use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
9- use rustc_hir:: { Block , Expr , HirId } ;
9+ use rustc_hir:: { Block , Expr , ExprKind , HirId } ;
1010use rustc_lint:: { LateContext , LateLintPass } ;
1111use rustc_middle:: hir:: map:: Map ;
1212use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
13- use rustc_span:: source_map:: Span ;
13+ use rustc_span:: { source_map:: Span , BytePos } ;
1414use std:: borrow:: Cow ;
1515
1616declare_clippy_lint ! {
@@ -218,14 +218,6 @@ fn lint_same_then_else<'tcx>(
218218 ) ;
219219
220220 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- )
229221 }
230222
231223 start_eq = start_eq. min ( current_start_eq) ;
@@ -328,7 +320,7 @@ fn emit_shared_code_in_if_blocks_lint(
328320 let suggestion = reindent_multiline ( Cow :: Borrowed ( & suggestion) , true , cond_indent) ;
329321
330322 let span = span_start. to ( span_end) ;
331- suggestions. push ( ( "START HELP " , span, suggestion. to_string ( ) ) ) ;
323+ suggestions. push ( ( "start " , span, suggestion. to_string ( ) ) ) ;
332324 }
333325
334326 if lint_end {
@@ -354,31 +346,56 @@ fn emit_shared_code_in_if_blocks_lint(
354346 let suggestion = "}\n " . to_string ( ) + & moved_snipped;
355347 let suggestion = reindent_multiline ( Cow :: Borrowed ( & suggestion) , true , indent) ;
356348
357- let span = moved_start. to ( span_end) ;
358- suggestions. push ( ( "END_RANGE" , span, suggestion. to_string ( ) ) ) ;
349+ let mut span = moved_start. to ( span_end) ;
350+ // Improve formatting if the inner block has indention (i.e. normal Rust formatting)
351+ let test_span = Span :: new ( span. lo ( ) - BytePos ( 4 ) , span. lo ( ) , span. ctxt ( ) ) ;
352+ if snippet_opt ( cx, test_span)
353+ . map ( |snip| snip == " " )
354+ . unwrap_or_default ( )
355+ {
356+ span = span. with_lo ( test_span. lo ( ) ) ;
357+ }
358+
359+ suggestions. push ( ( "end" , span, suggestion. to_string ( ) ) ) ;
359360 }
360361
361362 if suggestions. len ( ) == 1 {
362- let ( _, span, sugg) = & suggestions[ 0 ] ;
363+ let ( place_str, span, sugg) = suggestions. pop ( ) . unwrap ( ) ;
364+ let msg = format ! ( "All if blocks contain the same code at the {}" , place_str) ;
365+ let help = format ! ( "Consider moving the {} statements out like this" , place_str) ;
363366 span_lint_and_sugg (
364367 cx,
365368 SHARED_CODE_IN_IF_BLOCKS ,
366- * span,
367- "All code blocks contain the same code" ,
368- "Consider moving the statements out like this" ,
369- sugg. clone ( ) ,
369+ span,
370+ msg . as_str ( ) ,
371+ help . as_str ( ) ,
372+ sugg,
370373 Applicability :: Unspecified ,
371374 ) ;
372- } else {
375+ } else if suggestions. len ( ) == 2 {
376+ let ( _, end_span, end_sugg) = suggestions. pop ( ) . unwrap ( ) ;
377+ let ( _, start_span, start_sugg) = suggestions. pop ( ) . unwrap ( ) ;
373378 span_lint_and_then (
374379 cx,
375380 SHARED_CODE_IN_IF_BLOCKS ,
376- if_expr . span ,
377- "All if blocks contain the same code" ,
381+ start_span ,
382+ "All if blocks contain the same code at the start and the end. Here at the start: " ,
378383 move |diag| {
379- for ( help, span, sugg) in suggestions {
380- diag. span_suggestion ( span, help, sugg, Applicability :: Unspecified ) ;
381- }
384+ diag. span_note ( end_span, "And here at the end:" ) ;
385+
386+ diag. span_suggestion (
387+ start_span,
388+ "Consider moving the start statements out like this:" ,
389+ start_sugg,
390+ Applicability :: Unspecified ,
391+ ) ;
392+
393+ diag. span_suggestion (
394+ end_span,
395+ "And consider moving the end statements out like this:" ,
396+ end_sugg,
397+ Applicability :: Unspecified ,
398+ ) ;
382399 } ,
383400 ) ;
384401 }
0 commit comments