about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMario Carneiro <di.gama@gmail.com>2023-09-02 07:51:34 -0400
committerMario Carneiro <di.gama@gmail.com>2023-09-02 07:51:34 -0400
commitb3980d84976ae956a9a9f053b7fffe809b4a543e (patch)
tree6397f72a16e538da4645a3e75d1485d94958f960
parent39b316db61f350f5aafb186ab4b919587ead4777 (diff)
downloadrust-b3980d84976ae956a9a9f053b7fffe809b4a543e.tar.gz
rust-b3980d84976ae956a9a9f053b7fffe809b4a543e.zip
catch never loops through diverging functions
-rw-r--r--clippy_lints/src/loops/never_loop.rs11
-rw-r--r--tests/ui/never_loop.rs7
-rw-r--r--tests/ui/never_loop.stderr11
3 files changed, 26 insertions, 3 deletions
diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs
index 13f0ddc0ebf..5cdf0bd891f 100644
--- a/clippy_lints/src/loops/never_loop.rs
+++ b/clippy_lints/src/loops/never_loop.rs
@@ -148,7 +148,7 @@ fn never_loop_expr<'tcx>(
     local_labels: &mut Vec<(HirId, bool)>,
     main_loop_id: HirId,
 ) -> NeverLoopResult {
-    match expr.kind {
+    let result = match expr.kind {
         ExprKind::Unary(_, e)
         | ExprKind::Cast(e, _)
         | ExprKind::Type(e, _)
@@ -262,7 +262,14 @@ fn never_loop_expr<'tcx>(
         | ExprKind::ConstBlock(_)
         | ExprKind::Lit(_)
         | ExprKind::Err(_) => NeverLoopResult::Normal,
-    }
+    };
+    combine_seq(result, || {
+        if cx.typeck_results().expr_ty(expr).is_never() {
+            NeverLoopResult::Diverging
+        } else {
+            NeverLoopResult::Normal
+        }
+    })
 }
 
 fn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(
diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs
index ed18d79902c..33208364f0e 100644
--- a/tests/ui/never_loop.rs
+++ b/tests/ui/never_loop.rs
@@ -385,6 +385,13 @@ pub fn test31(b: bool) {
     }
 }
 
+pub fn test32(b: bool) {
+    loop {
+        //~^ ERROR: this loop never actually loops
+        panic!("oh no");
+    }
+}
+
 fn main() {
     test1();
     test2();
diff --git a/tests/ui/never_loop.stderr b/tests/ui/never_loop.stderr
index 188cd08b017..37ccd63d27c 100644
--- a/tests/ui/never_loop.stderr
+++ b/tests/ui/never_loop.stderr
@@ -161,5 +161,14 @@ LL | |                 if b { break 'c } else { break 'b }
 LL | |             }
    | |_____________^
 
-error: aborting due to 14 previous errors
+error: this loop never actually loops
+  --> $DIR/never_loop.rs:389:5
+   |
+LL | /     loop {
+LL | |
+LL | |         panic!("oh no");
+LL | |     }
+   | |_____^
+
+error: aborting due to 15 previous errors