]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
Auto merge of #103217 - mejrs:track, r=eholk
[rust.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 }