about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryanglsh <yanglsh@shanghaitech.edu.cn>2024-12-28 09:50:52 -0700
committeryanglsh <yanglsh@shanghaitech.edu.cn>2025-01-02 07:45:16 -0700
commitf18399fb69a07571f9a95732be5f6ec6b7517a78 (patch)
tree6e416f7a5f780dc36cdf285a05c9e4ab0ef1596f
parente582fcd75dda451c68c266d91d538f010f4a9b9f (diff)
downloadrust-f18399fb69a07571f9a95732be5f6ec6b7517a78.tar.gz
rust-f18399fb69a07571f9a95732be5f6ec6b7517a78.zip
Emit redundant if when duplicated in `needless_continue`
-rw-r--r--clippy_lints/src/needless_continue.rs29
-rw-r--r--tests/ui/needless_continue.rs26
-rw-r--r--tests/ui/needless_continue.stderr44
3 files changed, 90 insertions, 9 deletions
diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs
index dd75e0f4e4b..05b31fc84b9 100644
--- a/clippy_lints/src/needless_continue.rs
+++ b/clippy_lints/src/needless_continue.rs
@@ -78,14 +78,16 @@ declare_clippy_lint! {
     /// ```
     ///
     /// ```rust
-    /// fn foo() -> std::io::ErrorKind { std::io::ErrorKind::NotFound }
+    /// # use std::io::ErrorKind;
+    ///
+    /// fn foo() -> ErrorKind { ErrorKind::NotFound }
     /// for _ in 0..10 {
     ///     match foo() {
-    ///         std::io::ErrorKind::NotFound => {
+    ///         ErrorKind::NotFound => {
     ///             eprintln!("not found");
     ///             continue
     ///         }
-    ///         std::io::ErrorKind::TimedOut => {
+    ///         ErrorKind::TimedOut => {
     ///             eprintln!("timeout");
     ///             continue
     ///         }
@@ -100,13 +102,15 @@ declare_clippy_lint! {
     ///
     ///
     /// ```rust
-    /// fn foo() -> std::io::ErrorKind { std::io::ErrorKind::NotFound }
+    /// # use std::io::ErrorKind;
+    ///
+    /// fn foo() -> ErrorKind { ErrorKind::NotFound }
     /// for _ in 0..10 {
     ///     match foo() {
-    ///         std::io::ErrorKind::NotFound => {
+    ///         ErrorKind::NotFound => {
     ///             eprintln!("not found");
     ///         }
-    ///         std::io::ErrorKind::TimedOut => {
+    ///         ErrorKind::TimedOut => {
     ///             eprintln!("timeout");
     ///         }
     ///         _ => {
@@ -422,9 +426,10 @@ fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
                 );
             }
         };
-        check_last_stmt_in_block(loop_block, &p);
 
-        for (i, stmt) in loop_block.stmts.iter().enumerate() {
+        let stmts = &loop_block.stmts;
+        for (i, stmt) in stmts.iter().enumerate() {
+            let mut maybe_emitted_in_if = false;
             with_if_expr(stmt, |if_expr, cond, then_block, else_expr| {
                 let data = &LintData {
                     if_expr,
@@ -434,6 +439,8 @@ fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
                     stmt_idx: i,
                     loop_block,
                 };
+
+                maybe_emitted_in_if = true;
                 if needless_continue_in_else(else_expr, label) {
                     emit_warning(
                         cx,
@@ -443,8 +450,14 @@ fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
                     );
                 } else if is_first_block_stmt_continue(then_block, label) {
                     emit_warning(cx, data, DROP_ELSE_BLOCK_MSG, LintType::ContinueInsideThenBlock);
+                } else {
+                    maybe_emitted_in_if = false;
                 }
             });
+
+            if i == stmts.len() - 1 && !maybe_emitted_in_if {
+                check_last_stmt_in_block(loop_block, &p);
+            }
         }
     });
 }
diff --git a/tests/ui/needless_continue.rs b/tests/ui/needless_continue.rs
index bc7233f3ba5..334a2b32775 100644
--- a/tests/ui/needless_continue.rs
+++ b/tests/ui/needless_continue.rs
@@ -194,6 +194,32 @@ mod issue_4077 {
                 }
             }
         }
+
+        for _ in 0..10 {
+            match "foo".parse::<i32>() {
+                Ok(_) => do_something(),
+                Err(_) => {
+                    println!("bar-10");
+                    continue;
+                },
+            }
+        }
+
+        loop {
+            if true {
+            } else {
+                // redundant `else`
+                continue; // redundant `continue`
+            }
+        }
+
+        loop {
+            if some_expr() {
+                continue;
+            } else {
+                do_something();
+            }
+        }
     }
 
     // The contents of these functions are irrelevant, the purpose of this file is
diff --git a/tests/ui/needless_continue.stderr b/tests/ui/needless_continue.stderr
index 4ab443108b0..ec39d623419 100644
--- a/tests/ui/needless_continue.stderr
+++ b/tests/ui/needless_continue.stderr
@@ -168,5 +168,47 @@ LL |                     continue 'inner;
    |
    = help: consider dropping the `continue` expression
 
-error: aborting due to 12 previous errors
+error: this `continue` expression is redundant
+  --> tests/ui/needless_continue.rs:203:21
+   |
+LL |                     continue;
+   |                     ^^^^^^^^
+   |
+   = help: consider dropping the `continue` expression
+
+error: this `else` block is redundant
+  --> tests/ui/needless_continue.rs:210:20
+   |
+LL |               } else {
+   |  ____________________^
+LL | |                 // redundant `else`
+LL | |                 continue; // redundant `continue`
+LL | |             }
+   | |_____________^
+   |
+   = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block
+                       if true {
+           // merged code follows:
+           
+                       }
+
+error: there is no need for an explicit `else` block for this `if` expression
+  --> tests/ui/needless_continue.rs:217:13
+   |
+LL | /             if some_expr() {
+LL | |                 continue;
+LL | |             } else {
+LL | |                 do_something();
+LL | |             }
+   | |_____________^
+   |
+   = help: consider dropping the `else` clause
+                       if some_expr() {
+                           continue;
+                       }
+                       {
+                           do_something();
+                       }
+
+error: aborting due to 15 previous errors