Skip to content

Commit b6c9b09

Browse files
committed
Add lint for exit
1 parent c0b2411 commit b6c9b09

File tree

5 files changed

+58
-0
lines changed

5 files changed

+58
-0
lines changed

clippy_lints/src/exit.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::utils::{match_def_path, paths, qpath_res, span_lint};
2+
use if_chain::if_chain;
3+
use rustc::hir::{Expr, ExprKind};
4+
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
5+
use rustc::{declare_lint_pass, declare_tool_lint};
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** `exit()` terminates the program and doesn't provide a
9+
/// stack trace.
10+
///
11+
/// **Why is this bad?** Ideally a program is terminated by finishing
12+
/// the main function.
13+
///
14+
/// **Known problems:** This can be valid code in main() to return
15+
/// errors
16+
///
17+
/// **Example:**
18+
/// ```ignore
19+
/// std::process::exit(0)
20+
/// ```
21+
pub EXIT,
22+
restriction,
23+
"`std::process::exit` is called, terminating the program"
24+
}
25+
26+
declare_lint_pass!(Exit => [EXIT]);
27+
28+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Exit {
29+
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
30+
if_chain! {
31+
if let ExprKind::Call(ref path_expr, ref _args) = e.kind;
32+
if let ExprKind::Path(ref path) = path_expr.kind;
33+
if let Some(def_id) = qpath_res(cx, path, path_expr.hir_id).opt_def_id();
34+
if match_def_path(cx, def_id, &paths::EXIT);
35+
then {
36+
span_lint(cx, EXIT, e.span, "usage of `process::exit`");
37+
}
38+
39+
}
40+
}
41+
}

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ pub mod escape;
187187
pub mod eta_reduction;
188188
pub mod eval_order_dependence;
189189
pub mod excessive_precision;
190+
pub mod exit;
190191
pub mod explicit_write;
191192
pub mod fallible_impl_from;
192193
pub mod format;
@@ -610,6 +611,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
610611
reg.register_late_lint_pass(box comparison_chain::ComparisonChain);
611612
reg.register_late_lint_pass(box mul_add::MulAddCheck);
612613
reg.register_late_lint_pass(box unused_self::UnusedSelf);
614+
reg.register_late_lint_pass(box exit::Exit);
613615

614616
reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
615617
arithmetic::FLOAT_ARITHMETIC,

clippy_lints/src/utils/paths.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub const DROP: [&str; 3] = ["core", "mem", "drop"];
2727
pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"];
2828
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
2929
pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
30+
pub const EXIT: [&str; 3] = ["std", "process", "exit"];
3031
pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
3132
pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
3233
pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];

tests/ui/exit.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[warn(clippy::exit)]
2+
fn main() {
3+
std::process::exit(1);
4+
}

tests/ui/exit.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: usage of `process::exit`
2+
--> $DIR/exit.rs:3:5
3+
|
4+
LL | std::process::exit(1);
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::exit` implied by `-D warnings`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)