11use  clippy_utils:: diagnostics:: span_lint_and_help; 
2- use  clippy_utils:: source:: { indent_of,  snippet,  snippet_block,  snippet_with_context} ; 
2+ use  clippy_utils:: macros:: root_macro_call; 
3+ use  clippy_utils:: source:: { indent_of,  snippet_block,  snippet_with_context} ; 
34use  clippy_utils:: { higher,  is_from_proc_macro} ; 
45use  rustc_ast:: Label ; 
56use  rustc_errors:: Applicability ; 
@@ -132,7 +133,12 @@ declare_lint_pass!(NeedlessContinue => [NEEDLESS_CONTINUE]);
132133
133134impl < ' tcx >  LateLintPass < ' tcx >  for  NeedlessContinue  { 
134135    fn  check_expr ( & mut  self ,  cx :  & LateContext < ' tcx > ,  expr :  & ' tcx  Expr < ' tcx > )  { 
135-         if  !expr. span . in_external_macro ( cx. sess ( ) . source_map ( ) )  && !is_from_proc_macro ( cx,  expr)  { 
136+         // We cannot use `from_expansion` because for loops, while loops and while let loops are desugared 
137+         // into `loop` expressions. 
138+         if  !expr. span . in_external_macro ( cx. sess ( ) . source_map ( ) ) 
139+             && !is_from_proc_macro ( cx,  expr) 
140+             && root_macro_call ( expr. span ) . is_none ( ) 
141+         { 
136142            check_and_warn ( cx,  expr) ; 
137143        } 
138144    } 
@@ -193,15 +199,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessContinue {
193199/// - The expression node is a block with the first statement being a `continue`. 
194200fn  needless_continue_in_else ( else_expr :  & Expr < ' _ > ,  label :  Option < & Label > )  -> bool  { 
195201    match  else_expr. kind  { 
196-         ExprKind :: Block ( ref   else_block,  _)  => is_first_block_stmt_continue ( else_block,  label) , 
202+         ExprKind :: Block ( else_block,  _)  => is_first_block_stmt_continue ( else_block,  label) , 
197203        ExprKind :: Continue ( l)  => compare_labels ( label,  l. label . as_ref ( ) ) , 
198204        _ => false , 
199205    } 
200206} 
201207
202208fn  is_first_block_stmt_continue ( block :  & Block < ' _ > ,  label :  Option < & Label > )  -> bool  { 
203209    block. stmts . first ( ) . is_some_and ( |stmt| match  stmt. kind  { 
204-         StmtKind :: Semi ( ref   e)  | StmtKind :: Expr ( ref   e)  => { 
210+         StmtKind :: Semi ( e)  | StmtKind :: Expr ( e)  => { 
205211            if  let  ExprKind :: Continue ( ref  l)  = e. kind  { 
206212                compare_labels ( label,  l. label . as_ref ( ) ) 
207213            }  else  { 
@@ -366,7 +372,14 @@ fn suggestion_snippet_for_continue_inside_if(cx: &LateContext<'_>, data: &LintDa
366372} 
367373
368374fn  suggestion_snippet_for_continue_inside_else ( cx :  & LateContext < ' _ > ,  data :  & LintData < ' _ > )  -> String  { 
369-     let  cond_code = snippet ( cx,  data. if_cond . span ,  ".." ) ; 
375+     let  mut  applicability = Applicability :: MachineApplicable ; 
376+     let  ( cond_code,  _)  = snippet_with_context ( 
377+         cx, 
378+         data. if_cond . span , 
379+         data. if_expr . span . ctxt ( ) , 
380+         ".." , 
381+         & mut  applicability, 
382+     ) ; 
370383
371384    // Region B 
372385    let  block_code = erode_from_back ( & snippet_block ( cx,  data. if_block . span ,  ".." ,  Some ( data. if_expr . span ) ) ) ; 
@@ -402,7 +415,7 @@ fn suggestion_snippet_for_continue_inside_else(cx: &LateContext<'_>, data: &Lint
402415        } 
403416        lines. join ( "\n " ) 
404417    }  else  { 
405-         "" . to_string ( ) 
418+         String :: new ( ) 
406419    } ; 
407420
408421    let  indent_if = indent_of ( cx,  data. if_expr . span ) . unwrap_or ( 0 ) ; 
@@ -417,7 +430,7 @@ fn check_last_stmt_in_expr<F>(cx: &LateContext<'_>, inner_expr: &Expr<'_>, func:
417430where 
418431    F :  Fn ( Option < & Label > ,  Span ) , 
419432{ 
420-     match  & inner_expr. kind  { 
433+     match  inner_expr. kind  { 
421434        ExprKind :: Continue ( continue_label)  => { 
422435            func ( continue_label. label . as_ref ( ) ,  inner_expr. span ) ; 
423436        } , 
@@ -432,7 +445,7 @@ where
432445            if  !match_ty. is_unit ( )  && !match_ty. is_never ( )  { 
433446                return ; 
434447            } 
435-             for  arm in  arms. iter ( )  { 
448+             for  arm in  arms { 
436449                check_last_stmt_in_expr ( cx,  arm. body ,  func) ; 
437450            } 
438451        } , 
0 commit comments