From 3807634a470b572303d95feb8a5db273c7cea4af Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sun, 11 Oct 2020 16:04:33 -0700 Subject: [PATCH] clippy_lints: Update empty_loop lint We also update the documentation to note that the remediations are different for `std` and `no_std` crates. Signed-off-by: Joe Richey --- clippy_lints/src/loops.rs | 29 +++++++++++++++---- tests/ui/crashes/ice-360.stderr | 3 +- tests/ui/empty_loop.stderr | 11 +++++-- .../{issue-3746.rs => empty_loop_no_std.rs} | 0 4 files changed, 33 insertions(+), 10 deletions(-) rename tests/ui/{issue-3746.rs => empty_loop_no_std.rs} (100%) diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 63d7e3176b1..bae12943869 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -293,9 +293,24 @@ declare_clippy_lint! { declare_clippy_lint! { /// **What it does:** Checks for empty `loop` expressions. /// - /// **Why is this bad?** Those busy loops burn CPU cycles without doing - /// anything. Think of the environment and either block on something or at least - /// make the thread sleep for some microseconds. + /// **Why is this bad?** These busy loops burn CPU cycles without doing + /// anything. It is _almost always_ a better idea to `panic!` than to have + /// a busy loop. + /// + /// If panicking isn't possible, think of the environment and either: + /// - block on something + /// - sleep the thread for some microseconds + /// - yield or pause the thread + /// + /// For `std` targets, this can be done with + /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html) + /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html). + /// + /// For `no_std` targets, doing this is more complicated, especially because + /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will + /// probably need to invoke some target-specific intrinsic. Examples include: + /// - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html) + /// - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html) /// /// **Known problems:** None. /// @@ -502,13 +517,15 @@ impl<'tcx> LateLintPass<'tcx> for Loops { // (even if the "match" or "if let" is used for declaration) if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind { // also check for empty `loop {}` statements + // TODO(issue #6161): Enable for no_std crates (outside of #[panic_handler]) if block.stmts.is_empty() && block.expr.is_none() && !is_no_std_crate(cx.tcx.hir().krate()) { - span_lint( + span_lint_and_help( cx, EMPTY_LOOP, expr.span, - "empty `loop {}` detected. You may want to either use `panic!()` or add \ - `std::thread::sleep(..);` to the loop body.", + "empty `loop {}` wastes CPU cycles", + None, + "You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body.", ); } diff --git a/tests/ui/crashes/ice-360.stderr b/tests/ui/crashes/ice-360.stderr index 84e31eaf2e9..bb03ce40355 100644 --- a/tests/ui/crashes/ice-360.stderr +++ b/tests/ui/crashes/ice-360.stderr @@ -12,13 +12,14 @@ LL | | } | = note: `-D clippy::while-let-loop` implied by `-D warnings` -error: empty `loop {}` detected. You may want to either use `panic!()` or add `std::thread::sleep(..);` to the loop body. +error: empty `loop {}` wastes CPU cycles --> $DIR/ice-360.rs:10:9 | LL | loop {} | ^^^^^^^ | = note: `-D clippy::empty-loop` implied by `-D warnings` + = help: You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body. error: aborting due to 2 previous errors diff --git a/tests/ui/empty_loop.stderr b/tests/ui/empty_loop.stderr index e44c58ea770..fd3979f259a 100644 --- a/tests/ui/empty_loop.stderr +++ b/tests/ui/empty_loop.stderr @@ -1,22 +1,27 @@ -error: empty `loop {}` detected. You may want to either use `panic!()` or add `std::thread::sleep(..);` to the loop body. +error: empty `loop {}` wastes CPU cycles --> $DIR/empty_loop.rs:9:5 | LL | loop {} | ^^^^^^^ | = note: `-D clippy::empty-loop` implied by `-D warnings` + = help: You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body. -error: empty `loop {}` detected. You may want to either use `panic!()` or add `std::thread::sleep(..);` to the loop body. +error: empty `loop {}` wastes CPU cycles --> $DIR/empty_loop.rs:11:9 | LL | loop {} | ^^^^^^^ + | + = help: You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body. -error: empty `loop {}` detected. You may want to either use `panic!()` or add `std::thread::sleep(..);` to the loop body. +error: empty `loop {}` wastes CPU cycles --> $DIR/empty_loop.rs:15:9 | LL | 'inner: loop {} | ^^^^^^^^^^^^^^^ + | + = help: You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body. error: aborting due to 3 previous errors diff --git a/tests/ui/issue-3746.rs b/tests/ui/empty_loop_no_std.rs similarity index 100% rename from tests/ui/issue-3746.rs rename to tests/ui/empty_loop_no_std.rs