use super::EMPTY_LOOP; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::{is_in_panic_handler, is_no_std_crate, sym}; use rustc_hir::{Block, Expr, ItemKind, Node}; use rustc_lint::LateContext; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) { let parent_hir_id = cx.tcx.parent_hir_id(expr.hir_id); if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id) && matches!(parent_node.kind, ItemKind::Fn { .. }) && let attrs = cx.tcx.hir_attrs(parent_hir_id) && attrs.iter().any(|attr| attr.has_name(sym::rustc_intrinsic)) { // Intrinsic functions are expanded into an empty loop when lowering the AST // to simplify the job of later passes which might expect any function to have a body. return; } if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) { let msg = "empty `loop {}` wastes CPU cycles"; let help = if is_no_std_crate(cx) { "you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body" } else { "you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body" }; span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help); } }