]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / panic_unimplemented.rs
1 use clippy_utils::diagnostics::span_lint;
2 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
3 use rustc_hir::Expr;
4 use rustc_lint::{LateContext, LateLintPass};
5 use rustc_session::{declare_lint_pass, declare_tool_lint};
6
7 declare_clippy_lint! {
8 /// ### What it does
9 /// Checks for usage of `panic!`.
10 ///
11 /// ### Why is this bad?
12 /// `panic!` will stop the execution of the executable
13 ///
14 /// ### Example
15 /// ```no_run
16 /// panic!("even with a good reason");
17 /// ```
18 #[clippy::version = "1.40.0"]
19 pub PANIC,
20 restriction,
21 "usage of the `panic!` macro"
22 }
23
24 declare_clippy_lint! {
25 /// ### What it does
26 /// Checks for usage of `unimplemented!`.
27 ///
28 /// ### Why is this bad?
29 /// This macro should not be present in production code
30 ///
31 /// ### Example
32 /// ```no_run
33 /// unimplemented!();
34 /// ```
35 #[clippy::version = "pre 1.29.0"]
36 pub UNIMPLEMENTED,
37 restriction,
38 "`unimplemented!` should not be present in production code"
39 }
40
41 declare_clippy_lint! {
42 /// ### What it does
43 /// Checks for usage of `todo!`.
44 ///
45 /// ### Why is this bad?
46 /// This macro should not be present in production code
47 ///
48 /// ### Example
49 /// ```no_run
50 /// todo!();
51 /// ```
52 #[clippy::version = "1.40.0"]
53 pub TODO,
54 restriction,
55 "`todo!` should not be present in production code"
56 }
57
58 declare_clippy_lint! {
59 /// ### What it does
60 /// Checks for usage of `unreachable!`.
61 ///
62 /// ### Why is this bad?
63 /// This macro can cause code to panic
64 ///
65 /// ### Example
66 /// ```no_run
67 /// unreachable!();
68 /// ```
69 #[clippy::version = "1.40.0"]
70 pub UNREACHABLE,
71 restriction,
72 "usage of the `unreachable!` macro"
73 }
74
75 declare_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]);
76
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) {
82 return;
83 }
84
85 span_lint(
86 cx,
87 PANIC,
88 macro_call.span,
89 "`panic` should not be present in production code",
90 );
91 return;
92 }
93 match cx.tcx.item_name(macro_call.def_id).as_str() {
94 "todo" => {
95 span_lint(
96 cx,
97 TODO,
98 macro_call.span,
99 "`todo` should not be present in production code",
100 );
101 },
102 "unimplemented" => {
103 span_lint(
104 cx,
105 UNIMPLEMENTED,
106 macro_call.span,
107 "`unimplemented` should not be present in production code",
108 );
109 },
110 "unreachable" => {
111 span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
112 },
113 _ => {},
114 }
115 }
116 }