1 use clippy_utils::diagnostics::span_lint;
2 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
4 use rustc_lint::{LateContext, LateLintPass};
5 use rustc_session::{declare_lint_pass, declare_tool_lint};
9 /// Checks for usage of `panic!`.
11 /// ### Why is this bad?
12 /// `panic!` will stop the execution of the executable
16 /// panic!("even with a good reason");
18 #[clippy::version = "1.40.0"]
21 "usage of the `panic!` macro"
24 declare_clippy_lint! {
26 /// Checks for usage of `unimplemented!`.
28 /// ### Why is this bad?
29 /// This macro should not be present in production code
35 #[clippy::version = "pre 1.29.0"]
38 "`unimplemented!` should not be present in production code"
41 declare_clippy_lint! {
43 /// Checks for usage of `todo!`.
45 /// ### Why is this bad?
46 /// This macro should not be present in production code
52 #[clippy::version = "1.40.0"]
55 "`todo!` should not be present in production code"
58 declare_clippy_lint! {
60 /// Checks for usage of `unreachable!`.
62 /// ### Why is this bad?
63 /// This macro can cause code to panic
69 #[clippy::version = "1.40.0"]
72 "usage of the `unreachable!` macro"
75 declare_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]);
77 impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
78 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
79 let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
80 if is_panic(cx, macro_call.def_id) {
81 if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
89 "`panic` should not be present in production code",
93 match cx.tcx.item_name(macro_call.def_id).as_str() {
99 "`todo` should not be present in production code",
107 "`unimplemented` should not be present in production code",
111 span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");