about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHeinz N. Gies <heinz@licenser.net>2019-10-18 21:09:42 +0200
committerHeinz N. Gies <heinz@licenser.net>2019-11-07 17:10:18 +0100
commit695aa59c6df35343ebbcb153f6249cde0d018139 (patch)
tree6568687cf11fc47b09bc49766d6fca22f116a290
parent7531a08eed84a86e96d1cffdd002654507819873 (diff)
downloadrust-695aa59c6df35343ebbcb153f6249cde0d018139.tar.gz
rust-695aa59c6df35343ebbcb153f6249cde0d018139.zip
Add lint for exit
-rw-r--r--clippy_lints/src/exit.rs41
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/utils/paths.rs1
-rw-r--r--tests/ui/exit.rs4
-rw-r--r--tests/ui/exit.stderr10
5 files changed, 58 insertions, 0 deletions
diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs
new file mode 100644
index 00000000000..222f84bd028
--- /dev/null
+++ b/clippy_lints/src/exit.rs
@@ -0,0 +1,41 @@
+use crate::utils::{match_def_path, paths, qpath_res, span_lint};
+use if_chain::if_chain;
+use rustc::hir::{Expr, ExprKind};
+use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
+use rustc::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// **What it does:** `exit()`  terminates the program and doesn't provide a
+    /// stack trace.
+    ///
+    /// **Why is this bad?** Ideally a program is terminated by finishing
+    /// the main function.
+    ///
+    /// **Known problems:** This can be valid code in main() to return
+    /// errors
+    ///
+    /// **Example:**
+    /// ```ignore
+    /// std::process::exit(0)
+    /// ```
+    pub EXIT,
+    restriction,
+    "`std::process::exit` is called, terminating the program"
+}
+
+declare_lint_pass!(Exit => [EXIT]);
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Exit {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
+        if_chain! {
+            if let ExprKind::Call(ref path_expr, ref _args) = e.kind;
+            if let ExprKind::Path(ref path) = path_expr.kind;
+            if let Some(def_id) = qpath_res(cx, path, path_expr.hir_id).opt_def_id();
+            if match_def_path(cx, def_id, &paths::EXIT);
+            then {
+                span_lint(cx, EXIT, e.span, "usage of `process::exit`");
+            }
+
+        }
+    }
+}
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 1bd117dae94..99bbaf32c29 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -188,6 +188,7 @@ pub mod escape;
 pub mod eta_reduction;
 pub mod eval_order_dependence;
 pub mod excessive_precision;
+pub mod exit;
 pub mod explicit_write;
 pub mod fallible_impl_from;
 pub mod format;
@@ -941,6 +942,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
     store.register_early_pass(move || box enum_variants::EnumVariantNames::new(enum_variant_name_threshold));
     store.register_late_pass(|| box unused_self::UnusedSelf);
     store.register_late_pass(|| box mutable_debug_assertion::DebugAssertWithMutCall);
+    reg.register_late_lint_pass(||box exit::Exit);
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
         LintId::of(&arithmetic::FLOAT_ARITHMETIC),
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index 9787517e505..042ca4ee7fd 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -27,6 +27,7 @@ pub const DROP: [&str; 3] = ["core", "mem", "drop"];
 pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"];
 pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
 pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
+pub const EXIT: [&str; 3] = ["std", "process", "exit"];
 pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
 pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
 pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
diff --git a/tests/ui/exit.rs b/tests/ui/exit.rs
new file mode 100644
index 00000000000..1850241c476
--- /dev/null
+++ b/tests/ui/exit.rs
@@ -0,0 +1,4 @@
+#[warn(clippy::exit)]
+fn main() {
+    std::process::exit(1);
+}
diff --git a/tests/ui/exit.stderr b/tests/ui/exit.stderr
new file mode 100644
index 00000000000..4fd29439550
--- /dev/null
+++ b/tests/ui/exit.stderr
@@ -0,0 +1,10 @@
+error: usage of `process::exit`
+  --> $DIR/exit.rs:3:5
+   |
+LL |     std::process::exit(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::exit` implied by `-D warnings`
+
+error: aborting due to previous error
+