diff options
| author | dswij <dharmasw@outlook.com> | 2025-08-23 12:24:47 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-23 12:24:47 +0000 |
| commit | 36ef39522785dbc069c7e3b58c9142fc2b234bc6 (patch) | |
| tree | 2bbc68b3d445328aefba0583107f99593c49c315 | |
| parent | 7d43319e0cf244bd560cac238e0ce428d90dab94 (diff) | |
| parent | 8a988658a7caba4d7caf6926ba3b78e5f52d54f6 (diff) | |
| download | rust-36ef39522785dbc069c7e3b58c9142fc2b234bc6.tar.gz rust-36ef39522785dbc069c7e3b58c9142fc2b234bc6.zip | |
Detect infinite loop in `async fn` not returning `!` (#15545)
This fixes an overzealous change made to avoid signaling infinite loops in anonymous blocks that may never be used. Fixes rust-lang/rust-clippy#15541 r? @dswij changelog: none
| -rw-r--r-- | clippy_lints/src/loops/infinite_loop.rs | 9 | ||||
| -rw-r--r-- | tests/ui/infinite_loops.rs | 15 | ||||
| -rw-r--r-- | tests/ui/infinite_loops.stderr | 12 |
3 files changed, 33 insertions, 3 deletions
diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/infinite_loop.rs index a71e6963f8c..74c0b178018 100644 --- a/clippy_lints/src/loops/infinite_loop.rs +++ b/clippy_lints/src/loops/infinite_loop.rs @@ -4,7 +4,8 @@ use hir::intravisit::{Visitor, walk_expr}; use rustc_ast::Label; use rustc_errors::Applicability; use rustc_hir::{ - self as hir, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, Expr, ExprKind, FnRetTy, FnSig, Node, TyKind, + self as hir, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnRetTy, + FnSig, Node, TyKind, }; use rustc_lint::{LateContext, LintContext}; use rustc_span::sym; @@ -73,7 +74,11 @@ fn is_inside_unawaited_async_block(cx: &LateContext<'_>, expr: &Expr<'_>) -> boo if let Node::Expr(Expr { kind: ExprKind::Closure(Closure { - kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)), + kind: + ClosureKind::Coroutine(CoroutineKind::Desugared( + CoroutineDesugaring::Async, + CoroutineSource::Block | CoroutineSource::Closure, + )), .. }), .. diff --git a/tests/ui/infinite_loops.rs b/tests/ui/infinite_loops.rs index 9b8c3933197..7d01a7fb61f 100644 --- a/tests/ui/infinite_loops.rs +++ b/tests/ui/infinite_loops.rs @@ -521,4 +521,19 @@ mod tokio_spawn_test { } } +mod issue15541 { + async fn good() -> ! { + loop { + std::future::pending().await + } + } + + async fn bad() { + //~v infinite_loop + loop { + std::future::pending().await + } + } +} + fn main() {} diff --git a/tests/ui/infinite_loops.stderr b/tests/ui/infinite_loops.stderr index 4c6b6f725f1..319f1e5012b 100644 --- a/tests/ui/infinite_loops.stderr +++ b/tests/ui/infinite_loops.stderr @@ -333,5 +333,15 @@ LL | | } | = help: if this is not intended, try adding a `break` or `return` condition in the loop -error: aborting due to 23 previous errors +error: infinite loop detected + --> tests/ui/infinite_loops.rs:533:9 + | +LL | / loop { +LL | | std::future::pending().await +LL | | } + | |_________^ + | + = help: if this is not intended, try adding a `break` or `return` condition in the loop + +error: aborting due to 24 previous errors |
