11use clippy_utils:: diagnostics:: span_lint_and_help;
2- use clippy_utils:: source :: { indent_of , snippet , snippet_block , snippet_with_context } ;
3- use clippy_utils:: { higher , is_from_proc_macro } ;
2+ use clippy_utils:: higher ;
3+ use clippy_utils:: source :: { indent_of , snippet_block , snippet_with_context } ;
44use rustc_ast:: Label ;
55use rustc_errors:: Applicability ;
66use rustc_hir:: { Block , Expr , ExprKind , LoopSource , StmtKind } ;
77use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
88use rustc_session:: declare_lint_pass;
9- use rustc_span:: Span ;
9+ use rustc_span:: { ExpnKind , Span } ;
1010
1111declare_clippy_lint ! {
1212 /// ### What it does
@@ -132,7 +132,9 @@ declare_lint_pass!(NeedlessContinue => [NEEDLESS_CONTINUE]);
132132
133133impl < ' tcx > LateLintPass < ' tcx > for NeedlessContinue {
134134 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) {
135+ // We cannot use `from_expansion` because for loops, while loops and while let loops are desugared
136+ // into `loop` expressions.
137+ if !matches ! ( expr. span. ctxt( ) . outer_expn_data( ) . kind, ExpnKind :: Macro ( ..) ) {
136138 check_and_warn ( cx, expr) ;
137139 }
138140 }
@@ -193,16 +195,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessContinue {
193195/// - The expression node is a block with the first statement being a `continue`.
194196fn needless_continue_in_else ( else_expr : & Expr < ' _ > , label : Option < & Label > ) -> bool {
195197 match else_expr. kind {
196- ExprKind :: Block ( ref else_block, _) => is_first_block_stmt_continue ( else_block, label) ,
198+ ExprKind :: Block ( else_block, _) => is_first_block_stmt_continue ( else_block, label) ,
197199 ExprKind :: Continue ( l) => compare_labels ( label, l. label . as_ref ( ) ) ,
198200 _ => false ,
199201 }
200202}
201203
202204fn is_first_block_stmt_continue ( block : & Block < ' _ > , label : Option < & Label > ) -> bool {
203205 block. stmts . first ( ) . is_some_and ( |stmt| match stmt. kind {
204- StmtKind :: Semi ( ref e) | StmtKind :: Expr ( ref e) => {
205- if let ExprKind :: Continue ( ref l) = e. kind {
206+ StmtKind :: Semi ( e) | StmtKind :: Expr ( e) => {
207+ if let ExprKind :: Continue ( l) = e. kind {
206208 compare_labels ( label, l. label . as_ref ( ) )
207209 } else {
208210 false
@@ -225,10 +227,10 @@ fn compare_labels(loop_label: Option<&Label>, continue_label: Option<&Label>) ->
225227}
226228
227229/// If `expr` is a loop expression (while/while let/for/loop), calls `func` with
228- /// the AST object representing the loop block of `expr`.
229- fn with_loop_block < ' tcx , F > ( expr : & Expr < ' tcx > , mut func : F )
230+ /// the HIR object representing the loop block of `expr`.
231+ fn with_loop_block < F > ( expr : & Expr < ' _ > , mut func : F )
230232where
231- F : FnMut ( & Block < ' tcx > , Option < & Label > ) ,
233+ F : FnMut ( & Block < ' _ > , Option < & Label > ) ,
232234{
233235 if let Some ( higher:: ForLoop { body, label, .. } ) = higher:: ForLoop :: hir ( expr)
234236 && let ExprKind :: Block ( block, _) = & body. kind
@@ -264,9 +266,9 @@ where
264266/// - The `if` condition expression,
265267/// - The `then` block, and
266268/// - The `else` expression.
267- fn with_if_expr < ' tcx , F > ( expr : & Expr < ' tcx > , mut func : F )
269+ fn with_if_expr < F > ( expr : & Expr < ' _ > , mut func : F )
268270where
269- F : FnMut ( & Expr < ' tcx > , & Expr < ' tcx > , & Block < ' tcx > , & Expr < ' tcx > ) ,
271+ F : FnMut ( & Expr < ' _ > , & Expr < ' _ > , & Block < ' _ > , & Expr < ' _ > ) ,
270272{
271273 if let Some ( higher:: If {
272274 cond,
@@ -288,20 +290,20 @@ enum LintType {
288290
289291/// Data we pass around for construction of help messages.
290292#[ derive( Debug ) ]
291- struct LintData < ' tcx > {
293+ struct LintData < ' hir > {
292294 /// The `if` expression encountered in the above loop.
293- if_expr : & ' tcx Expr < ' tcx > ,
295+ if_expr : & ' hir Expr < ' hir > ,
294296 /// The condition expression for the above `if`.
295- if_cond : & ' tcx Expr < ' tcx > ,
297+ if_cond : & ' hir Expr < ' hir > ,
296298 /// The `then` block of the `if` statement.
297- if_block : & ' tcx Block < ' tcx > ,
299+ if_block : & ' hir Block < ' hir > ,
298300 /// The `else` block of the `if` statement.
299301 /// Note that we only work with `if` exprs that have an `else` branch.
300- else_expr : & ' tcx Expr < ' tcx > ,
302+ else_expr : & ' hir Expr < ' hir > ,
301303 /// The 0-based index of the `if` statement in the containing loop block.
302304 stmt_idx : Option < usize > ,
303305 /// The statements of the loop block.
304- loop_block : & ' tcx Block < ' tcx > ,
306+ loop_block : & ' hir Block < ' hir > ,
305307}
306308
307309const MSG_REDUNDANT_CONTINUE_EXPRESSION : & str = "this `continue` expression is redundant" ;
@@ -366,7 +368,14 @@ fn suggestion_snippet_for_continue_inside_if(cx: &LateContext<'_>, data: &LintDa
366368}
367369
368370fn suggestion_snippet_for_continue_inside_else ( cx : & LateContext < ' _ > , data : & LintData < ' _ > ) -> String {
369- let cond_code = snippet ( cx, data. if_cond . span , ".." ) ;
371+ let mut applicability = Applicability :: MachineApplicable ;
372+ let ( cond_code, _) = snippet_with_context (
373+ cx,
374+ data. if_cond . span ,
375+ data. if_expr . span . ctxt ( ) ,
376+ ".." ,
377+ & mut applicability,
378+ ) ;
370379
371380 // Region B
372381 let block_code = erode_from_back ( & snippet_block ( cx, data. if_block . span , ".." , Some ( data. if_expr . span ) ) ) ;
@@ -402,7 +411,7 @@ fn suggestion_snippet_for_continue_inside_else(cx: &LateContext<'_>, data: &Lint
402411 }
403412 lines. join ( "\n " )
404413 } else {
405- "" . to_string ( )
414+ String :: new ( )
406415 } ;
407416
408417 let indent_if = indent_of ( cx, data. if_expr . span ) . unwrap_or ( 0 ) ;
@@ -417,7 +426,7 @@ fn check_last_stmt_in_expr<F>(cx: &LateContext<'_>, inner_expr: &Expr<'_>, func:
417426where
418427 F : Fn ( Option < & Label > , Span ) ,
419428{
420- match & inner_expr. kind {
429+ match inner_expr. kind {
421430 ExprKind :: Continue ( continue_label) => {
422431 func ( continue_label. label . as_ref ( ) , inner_expr. span ) ;
423432 } ,
@@ -432,7 +441,7 @@ where
432441 if !match_ty. is_unit ( ) && !match_ty. is_never ( ) {
433442 return ;
434443 }
435- for arm in arms. iter ( ) {
444+ for arm in arms {
436445 check_last_stmt_in_expr ( cx, arm. body , func) ;
437446 }
438447 } ,
0 commit comments