]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/panic_unimplemented.rs
Split out `infalliable_detructuring_match`
[rust.git] / clippy_lints / src / panic_unimplemented.rs
index 1e9468589472326ad23098a935f3de9ff052a747..6ef6b9a20aa4b185211eaa6c96c48dae49d11af0 100644 (file)
@@ -1,70 +1,72 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{is_expn_of, match_panic_call};
-use if_chain::if_chain;
+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};
-use rustc_span::Span;
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for usage of `panic!`.
+    /// ### What it does
+    /// Checks for usage of `panic!`.
     ///
-    /// **Why is this bad?** `panic!` will stop the execution of the executable
+    /// ### Why is this bad?
+    /// `panic!` will stop the execution of the executable
     ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
+    /// ### 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
+    /// ### What it does
+    /// Checks for usage of `unimplemented!`.
     ///
-    /// **Known problems:** None.
+    /// ### Why is this bad?
+    /// This macro should not be present in production code
     ///
-    /// **Example:**
+    /// ### 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
+    /// ### What it does
+    /// Checks for usage of `todo!`.
     ///
-    /// **Known problems:** None.
+    /// ### Why is this bad?
+    /// This macro should not be present in production code
     ///
-    /// **Example:**
+    /// ### 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!`.
+    /// ### What it does
+    /// Checks for usage of `unreachable!`.
     ///
-    /// **Why is this bad?** This macro can cause code to panic
+    /// ### Why is this bad?
+    /// This macro can cause code to panic
     ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
+    /// ### Example
     /// ```no_run
     /// unreachable!();
     /// ```
+    #[clippy::version = "1.40.0"]
     pub UNREACHABLE,
     restriction,
     "usage of the `unreachable!` macro"
 
 impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if match_panic_call(cx, expr).is_some() {
-            let span = get_outer_span(expr);
-            if is_expn_of(expr.span, "unimplemented").is_some() {
+        let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
+        if is_panic(cx, macro_call.def_id) {
+            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,
-                    span,
+                    macro_call.span,
                     "`unimplemented` should not be present in production code",
                 );
-            } else if is_expn_of(expr.span, "todo").is_some() {
-                span_lint(cx, TODO, span, "`todo` should not be present in production code");
-            } else if is_expn_of(expr.span, "unreachable").is_some() {
-                span_lint(cx, UNREACHABLE, span, "usage of the `unreachable!` macro");
-            } else if is_expn_of(expr.span, "panic").is_some() {
-                span_lint(cx, PANIC, span, "`panic` should not be present in production code");
-            }
-        }
-    }
-}
-
-fn get_outer_span(expr: &Expr<'_>) -> Span {
-    if_chain! {
-        if expr.span.from_expansion();
-        let first = expr.span.ctxt().outer_expn_data().call_site;
-        if first.from_expansion();
-        then {
-            first.ctxt().outer_expn_data().call_site
-        } else {
-            expr.span
+            },
+            "unreachable" => {
+                span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
+            },
+            _ => {},
         }
     }
 }