]> 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 d8d9081d6f172ab72da22e9ad1697f5a55e9b521..6ef6b9a20aa4b185211eaa6c96c48dae49d11af0 100644 (file)
@@ -1,10 +1,8 @@
 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
@@ -17,6 +15,7 @@
     /// ```no_run
     /// panic!("even with a good reason");
     /// ```
+    #[clippy::version = "1.40.0"]
     pub PANIC,
     restriction,
     "usage of the `panic!` macro"
@@ -33,6 +32,7 @@
     /// ```no_run
     /// unimplemented!();
     /// ```
+    #[clippy::version = "pre 1.29.0"]
     pub UNIMPLEMENTED,
     restriction,
     "`unimplemented!` should not be present in production code"
@@ -49,6 +49,7 @@
     /// ```no_run
     /// todo!();
     /// ```
+    #[clippy::version = "1.40.0"]
     pub TODO,
     restriction,
     "`todo!` should not be present in production code"
@@ -65,6 +66,7 @@
     /// ```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()
-            && (is_expn_of(expr.span, "debug_assert").is_none() && is_expn_of(expr.span, "assert").is_none())
-        {
-            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");
+            },
+            _ => {},
         }
     }
 }