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