From b3980d84976ae956a9a9f053b7fffe809b4a543e Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Sat, 2 Sep 2023 07:51:34 -0400 Subject: [PATCH] catch never loops through diverging functions --- clippy_lints/src/loops/never_loop.rs | 11 +++++++++-- tests/ui/never_loop.rs | 7 +++++++ tests/ui/never_loop.stderr | 11 ++++++++++- 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>>( 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