1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::macros::{root_macro_call, FormatArgsExpn};
3 use clippy_utils::source::snippet_with_applicability;
4 use clippy_utils::{peel_blocks_with_stmt, sugg};
5 use rustc_errors::Applicability;
6 use rustc_hir::{Expr, ExprKind, UnOp};
7 use rustc_lint::{LateContext, LateLintPass};
8 use rustc_session::{declare_lint_pass, declare_tool_lint};
11 declare_clippy_lint! {
13 /// Detects `if`-then-`panic!` that can be replaced with `assert!`.
15 /// ### Why is this bad?
16 /// `assert!` is simpler than `if`-then-`panic!`.
20 /// let sad_people: Vec<&str> = vec![];
21 /// if !sad_people.is_empty() {
22 /// panic!("there are sad people: {:?}", sad_people);
27 /// let sad_people: Vec<&str> = vec![];
28 /// assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people);
30 #[clippy::version = "1.57.0"]
33 "`panic!` and only a `panic!` in `if`-then statement"
36 declare_lint_pass!(ManualAssert => [MANUAL_ASSERT]);
38 impl<'tcx> LateLintPass<'tcx> for ManualAssert {
39 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
41 if let ExprKind::If(cond, then, None) = expr.kind;
42 if !matches!(cond.kind, ExprKind::Let(_));
43 if !expr.span.from_expansion();
44 let then = peel_blocks_with_stmt(then);
45 if let Some(macro_call) = root_macro_call(then.span);
46 if cx.tcx.item_name(macro_call.def_id) == sym::panic;
47 if !cx.tcx.sess.source_map().is_multiline(cond.span);
48 if let Some(format_args) = FormatArgsExpn::find_nested(cx, then, macro_call.expn);
50 let mut applicability = Applicability::MachineApplicable;
51 let format_args_snip = snippet_with_applicability(cx, format_args.inputs_span(), "..", &mut applicability);
52 let cond = cond.peel_drop_temps();
53 let (cond, not) = match cond.kind {
54 ExprKind::Unary(UnOp::Not, e) => (e, ""),
57 let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par();
58 let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});");
63 "only a `panic!` in `if`-then statement",
66 Applicability::MachineApplicable,