1
1
use 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} ;
3
4
use clippy_utils:: { higher, is_from_proc_macro} ;
4
5
use rustc_ast:: Label ;
5
6
use rustc_errors:: Applicability ;
@@ -132,7 +133,12 @@ declare_lint_pass!(NeedlessContinue => [NEEDLESS_CONTINUE]);
132
133
133
134
impl < ' tcx > LateLintPass < ' tcx > for NeedlessContinue {
134
135
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
+ {
136
142
check_and_warn ( cx, expr) ;
137
143
}
138
144
}
@@ -193,15 +199,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessContinue {
193
199
/// - The expression node is a block with the first statement being a `continue`.
194
200
fn needless_continue_in_else ( else_expr : & Expr < ' _ > , label : Option < & Label > ) -> bool {
195
201
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) ,
197
203
ExprKind :: Continue ( l) => compare_labels ( label, l. label . as_ref ( ) ) ,
198
204
_ => false ,
199
205
}
200
206
}
201
207
202
208
fn is_first_block_stmt_continue ( block : & Block < ' _ > , label : Option < & Label > ) -> bool {
203
209
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) => {
205
211
if let ExprKind :: Continue ( ref l) = e. kind {
206
212
compare_labels ( label, l. label . as_ref ( ) )
207
213
} else {
@@ -225,10 +231,10 @@ fn compare_labels(loop_label: Option<&Label>, continue_label: Option<&Label>) ->
225
231
}
226
232
227
233
/// 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 )
234
+ /// the HIR object representing the loop block of `expr`.
235
+ fn with_loop_block < F > ( expr : & Expr < ' _ > , mut func : F )
230
236
where
231
- F : FnMut ( & Block < ' tcx > , Option < & Label > ) ,
237
+ F : FnMut ( & Block < ' _ > , Option < & Label > ) ,
232
238
{
233
239
if let Some ( higher:: ForLoop { body, label, .. } ) = higher:: ForLoop :: hir ( expr)
234
240
&& let ExprKind :: Block ( block, _) = & body. kind
@@ -264,9 +270,9 @@ where
264
270
/// - The `if` condition expression,
265
271
/// - The `then` block, and
266
272
/// - The `else` expression.
267
- fn with_if_expr < ' tcx , F > ( expr : & Expr < ' tcx > , mut func : F )
273
+ fn with_if_expr < F > ( expr : & Expr < ' _ > , mut func : F )
268
274
where
269
- F : FnMut ( & Expr < ' tcx > , & Expr < ' tcx > , & Block < ' tcx > , & Expr < ' tcx > ) ,
275
+ F : FnMut ( & Expr < ' _ > , & Expr < ' _ > , & Block < ' _ > , & Expr < ' _ > ) ,
270
276
{
271
277
if let Some ( higher:: If {
272
278
cond,
@@ -288,20 +294,20 @@ enum LintType {
288
294
289
295
/// Data we pass around for construction of help messages.
290
296
#[ derive( Debug ) ]
291
- struct LintData < ' tcx > {
297
+ struct LintData < ' hir > {
292
298
/// The `if` expression encountered in the above loop.
293
- if_expr : & ' tcx Expr < ' tcx > ,
299
+ if_expr : & ' hir Expr < ' hir > ,
294
300
/// The condition expression for the above `if`.
295
- if_cond : & ' tcx Expr < ' tcx > ,
301
+ if_cond : & ' hir Expr < ' hir > ,
296
302
/// The `then` block of the `if` statement.
297
- if_block : & ' tcx Block < ' tcx > ,
303
+ if_block : & ' hir Block < ' hir > ,
298
304
/// The `else` block of the `if` statement.
299
305
/// Note that we only work with `if` exprs that have an `else` branch.
300
- else_expr : & ' tcx Expr < ' tcx > ,
306
+ else_expr : & ' hir Expr < ' hir > ,
301
307
/// The 0-based index of the `if` statement in the containing loop block.
302
308
stmt_idx : Option < usize > ,
303
309
/// The statements of the loop block.
304
- loop_block : & ' tcx Block < ' tcx > ,
310
+ loop_block : & ' hir Block < ' hir > ,
305
311
}
306
312
307
313
const MSG_REDUNDANT_CONTINUE_EXPRESSION : & str = "this `continue` expression is redundant" ;
@@ -366,7 +372,14 @@ fn suggestion_snippet_for_continue_inside_if(cx: &LateContext<'_>, data: &LintDa
366
372
}
367
373
368
374
fn 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
+ ) ;
370
383
371
384
// Region B
372
385
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
402
415
}
403
416
lines. join ( "\n " )
404
417
} else {
405
- "" . to_string ( )
418
+ String :: new ( )
406
419
} ;
407
420
408
421
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:
417
430
where
418
431
F : Fn ( Option < & Label > , Span ) ,
419
432
{
420
- match & inner_expr. kind {
433
+ match inner_expr. kind {
421
434
ExprKind :: Continue ( continue_label) => {
422
435
func ( continue_label. label . as_ref ( ) , inner_expr. span ) ;
423
436
} ,
@@ -432,7 +445,7 @@ where
432
445
if !match_ty. is_unit ( ) && !match_ty. is_never ( ) {
433
446
return ;
434
447
}
435
- for arm in arms. iter ( ) {
448
+ for arm in arms {
436
449
check_last_stmt_in_expr ( cx, arm. body , func) ;
437
450
}
438
451
} ,
0 commit comments