]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/exit.rs
bump version to 1.79.0+dfsg1-1~bpo12+pve2
[rustc.git] / src / tools / clippy / clippy_lints / src / exit.rs
CommitLineData
cdc7bbd5 1use clippy_utils::diagnostics::span_lint;
ed00b5ec 2use clippy_utils::is_entrypoint_fn;
f20569fa
XL
3use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
4use rustc_lint::{LateContext, LateLintPass};
4b012472 5use rustc_session::declare_lint_pass;
ed00b5ec 6use rustc_span::sym;
f20569fa
XL
7
8declare_clippy_lint! {
94222f64 9 /// ### What it does
487cf647 10 /// Detects calls to the `exit()` function which terminates the program.
f20569fa 11 ///
94222f64 12 /// ### Why is this bad?
487cf647 13 /// Exit terminates the program at the location it is called. For unrecoverable
353b0b11 14 /// errors `panics` should be used to provide a stacktrace and potentially other
487cf647 15 /// information. A normal termination or one with an error code should happen in
f20569fa
XL
16 /// the main function.
17 ///
94222f64 18 /// ### Example
ed00b5ec 19 /// ```no_run
f20569fa
XL
20 /// std::process::exit(0)
21 /// ```
487cf647
FG
22 ///
23 /// Use instead:
24 ///
25 /// ```ignore
26 /// // To provide a stacktrace and additional information
27 /// panic!("message");
28 ///
29 /// // or a main method with a return
30 /// fn main() -> Result<(), i32> {
31 /// Ok(())
32 /// }
33 /// ```
a2a8927a 34 #[clippy::version = "1.41.0"]
f20569fa
XL
35 pub EXIT,
36 restriction,
487cf647 37 "detects `std::process::exit` calls"
f20569fa
XL
38}
39
40declare_lint_pass!(Exit => [EXIT]);
41
42impl<'tcx> LateLintPass<'tcx> for Exit {
43 fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
4b012472
FG
44 if let ExprKind::Call(path_expr, _args) = e.kind
45 && let ExprKind::Path(ref path) = path_expr.kind
46 && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
47 && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
48 && let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id
c620b35d 49 && let Node::Item(Item{kind: ItemKind::Fn(..), ..}) = cx.tcx.hir_node_by_def_id(parent)
cdc7bbd5
XL
50 // If the next item up is a function we check if it is an entry point
51 // and only then emit a linter warning
4b012472
FG
52 && !is_entrypoint_fn(cx, parent.to_def_id())
53 {
54 span_lint(cx, EXIT, e.span, "usage of `process::exit`");
f20569fa
XL
55 }
56 }
57}