]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / panic_unimplemented.rs
CommitLineData
cdc7bbd5
XL
1use clippy_utils::diagnostics::span_lint;
2use clippy_utils::{is_expn_of, match_panic_call};
f20569fa
XL
3use if_chain::if_chain;
4use rustc_hir::Expr;
5use rustc_lint::{LateContext, LateLintPass};
6use rustc_session::{declare_lint_pass, declare_tool_lint};
7use rustc_span::Span;
8
9declare_clippy_lint! {
10 /// **What it does:** Checks for usage of `panic!`.
11 ///
12 /// **Why is this bad?** `panic!` will stop the execution of the executable
13 ///
14 /// **Known problems:** None.
15 ///
16 /// **Example:**
17 /// ```no_run
18 /// panic!("even with a good reason");
19 /// ```
20 pub PANIC,
21 restriction,
22 "usage of the `panic!` macro"
23}
24
25declare_clippy_lint! {
26 /// **What it does:** Checks for usage of `unimplemented!`.
27 ///
28 /// **Why is this bad?** This macro should not be present in production code
29 ///
30 /// **Known problems:** None.
31 ///
32 /// **Example:**
33 /// ```no_run
34 /// unimplemented!();
35 /// ```
36 pub UNIMPLEMENTED,
37 restriction,
38 "`unimplemented!` should not be present in production code"
39}
40
41declare_clippy_lint! {
42 /// **What it does:** Checks for usage of `todo!`.
43 ///
44 /// **Why is this bad?** This macro should not be present in production code
45 ///
46 /// **Known problems:** None.
47 ///
48 /// **Example:**
49 /// ```no_run
50 /// todo!();
51 /// ```
52 pub TODO,
53 restriction,
54 "`todo!` should not be present in production code"
55}
56
57declare_clippy_lint! {
58 /// **What it does:** Checks for usage of `unreachable!`.
59 ///
60 /// **Why is this bad?** This macro can cause code to panic
61 ///
62 /// **Known problems:** None.
63 ///
64 /// **Example:**
65 /// ```no_run
66 /// unreachable!();
67 /// ```
68 pub UNREACHABLE,
69 restriction,
70 "usage of the `unreachable!` macro"
71}
72
73declare_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]);
74
75impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
76 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
136023e0
XL
77 if match_panic_call(cx, expr).is_some()
78 && (is_expn_of(expr.span, "debug_assert").is_none() && is_expn_of(expr.span, "assert").is_none())
79 {
f20569fa
XL
80 let span = get_outer_span(expr);
81 if is_expn_of(expr.span, "unimplemented").is_some() {
82 span_lint(
83 cx,
84 UNIMPLEMENTED,
85 span,
86 "`unimplemented` should not be present in production code",
87 );
88 } else if is_expn_of(expr.span, "todo").is_some() {
89 span_lint(cx, TODO, span, "`todo` should not be present in production code");
90 } else if is_expn_of(expr.span, "unreachable").is_some() {
91 span_lint(cx, UNREACHABLE, span, "usage of the `unreachable!` macro");
92 } else if is_expn_of(expr.span, "panic").is_some() {
93 span_lint(cx, PANIC, span, "`panic` should not be present in production code");
94 }
95 }
96 }
97}
98
99fn get_outer_span(expr: &Expr<'_>) -> Span {
100 if_chain! {
101 if expr.span.from_expansion();
cdc7bbd5
XL
102 let first = expr.span.ctxt().outer_expn_data().call_site;
103 if first.from_expansion();
f20569fa 104 then {
cdc7bbd5 105 first.ctxt().outer_expn_data().call_site
f20569fa
XL
106 } else {
107 expr.span
108 }
109 }
110}