diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 91c97ef7c2a..1d19413e0d0 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -273,6 +273,8 @@ struct LintData<'a> { block_stmts: &'a [ast::Stmt], } +const MSG_REDUNDANT_CONTINUE_EXPRESSION: &str = "this `continue` expression is redundant"; + const MSG_REDUNDANT_ELSE_BLOCK: &str = "this `else` block is redundant"; const MSG_ELSE_BLOCK_NOT_NEEDED: &str = "there is no need for an explicit `else` block for this `if` \ @@ -283,6 +285,8 @@ struct LintData<'a> { const DROP_ELSE_BLOCK_MSG: &str = "consider dropping the `else` clause"; +const DROP_CONTINUE_EXPRESSION_MSG: &str = "consider dropping the `continue` expression"; + fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str, typ: LintType) { // snip is the whole *help* message that appears after the warning. // message is the warning message. @@ -364,6 +368,22 @@ fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data: } fn check_and_warn<'a>(cx: &EarlyContext<'_>, expr: &'a ast::Expr) { + if_chain! { + if let ast::ExprKind::Loop(loop_block, ..) = &expr.kind; + if let Some(last_stmt) = loop_block.stmts.last(); + if let ast::StmtKind::Expr(inner_expr) | ast::StmtKind::Semi(inner_expr) = &last_stmt.kind; + if let ast::ExprKind::Continue(_) = inner_expr.kind; + then { + span_lint_and_help( + cx, + NEEDLESS_CONTINUE, + last_stmt.span, + MSG_REDUNDANT_CONTINUE_EXPRESSION, + None, + DROP_CONTINUE_EXPRESSION_MSG, + ); + } + } with_loop_block(expr, |loop_block, label| { for (i, stmt) in loop_block.stmts.iter().enumerate() { with_if_expr(stmt, |if_expr, cond, then_block, else_expr| { diff --git a/tests/ui/needless_continue.rs b/tests/ui/needless_continue.rs index 5da95647f2c..83ee27f4887 100644 --- a/tests/ui/needless_continue.rs +++ b/tests/ui/needless_continue.rs @@ -51,6 +51,34 @@ fn main() { } } +fn simple_loop() { + loop { + continue; // should lint here + } +} + +fn simple_loop2() { + loop { + println!("bleh"); + continue; // should lint here + } +} + +#[rustfmt::skip] +fn simple_loop3() { + loop { + continue // should lint here + } +} + +#[rustfmt::skip] +fn simple_loop4() { + loop { + println!("bleh"); + continue // should lint here + } +} + mod issue_2329 { fn condition() -> bool { unimplemented!() diff --git a/tests/ui/needless_continue.stderr b/tests/ui/needless_continue.stderr index 8d6a37df960..22b86f25e8f 100644 --- a/tests/ui/needless_continue.stderr +++ b/tests/ui/needless_continue.stderr @@ -54,8 +54,40 @@ LL | | } println!("Jabber"); } +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:56:9 + | +LL | continue; // should lint here + | ^^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:63:9 + | +LL | continue; // should lint here + | ^^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:70:9 + | +LL | continue // should lint here + | ^^^^^^^^ + | + = help: consider dropping the `continue` expression + +error: this `continue` expression is redundant + --> $DIR/needless_continue.rs:78:9 + | +LL | continue // should lint here + | ^^^^^^^^ + | + = help: consider dropping the `continue` expression + error: this `else` block is redundant - --> $DIR/needless_continue.rs:100:24 + --> $DIR/needless_continue.rs:128:24 | LL | } else { | ________________________^ @@ -78,7 +110,7 @@ LL | | } } error: there is no need for an explicit `else` block for this `if` expression - --> $DIR/needless_continue.rs:106:17 + --> $DIR/needless_continue.rs:134:17 | LL | / if condition() { LL | | continue; // should lint here @@ -95,5 +127,5 @@ LL | | } println!("bar-5"); } -error: aborting due to 4 previous errors +error: aborting due to 8 previous errors