about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/panic_unimplemented.rs78
-rw-r--r--clippy_utils/src/paths.rs1
-rw-r--r--tests/ui-toml/panic/panic.rs5
-rw-r--r--tests/ui-toml/panic/panic.stderr10
4 files changed, 62 insertions, 32 deletions
diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs
index 4eefd0065f6..fa5b02a5a41 100644
--- a/clippy_lints/src/panic_unimplemented.rs
+++ b/clippy_lints/src/panic_unimplemented.rs
@@ -1,8 +1,9 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_in_test;
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
-use rustc_hir::Expr;
+use clippy_utils::{is_in_test, match_def_path, paths};
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 
@@ -95,10 +96,49 @@ impl_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC])
 
 impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if is_panic(cx, macro_call.def_id) {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr) {
+            if is_panic(cx, macro_call.def_id) {
+                if cx.tcx.hir().is_inside_const_context(expr.hir_id)
+                    || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
+                {
+                    return;
+                }
+
+                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,
+                        macro_call.span,
+                        "`unimplemented` should not be present in production code",
+                    );
+                },
+                "unreachable" => {
+                    span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
+                },
+                _ => {},
+            }
+        } else if let ExprKind::Call(func, [_]) = expr.kind
+            && let ExprKind::Path(QPath::Resolved(None, expr_path)) = func.kind
+            && let Res::Def(DefKind::Fn, def_id) = expr_path.res
+            && match_def_path(cx, def_id, &paths::PANIC_ANY)
+        {
             if cx.tcx.hir().is_inside_const_context(expr.hir_id)
                 || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
             {
@@ -108,32 +148,10 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
             span_lint(
                 cx,
                 PANIC,
-                macro_call.span,
-                "`panic` should not be present in production code",
+                expr.span,
+                "`panic_any` 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,
-                    macro_call.span,
-                    "`unimplemented` should not be present in production code",
-                );
-            },
-            "unreachable" => {
-                span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
-            },
-            _ => {},
-        }
     }
 }
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index 684c645c199..a767798a9c3 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -56,6 +56,7 @@ pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to
 pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
 pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"];
 pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
+pub const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"];
 pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
 pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"];
 pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
diff --git a/tests/ui-toml/panic/panic.rs b/tests/ui-toml/panic/panic.rs
index 618a37ddfc5..b6264c950e4 100644
--- a/tests/ui-toml/panic/panic.rs
+++ b/tests/ui-toml/panic/panic.rs
@@ -1,5 +1,6 @@
 //@compile-flags: --test
 #![warn(clippy::panic)]
+use std::panic::panic_any;
 
 fn main() {
     enum Enam {
@@ -12,6 +13,10 @@ fn main() {
     }
 }
 
+fn issue_13292() {
+    panic_any("should lint")
+}
+
 #[test]
 fn lonely_test() {
     enum Enam {
diff --git a/tests/ui-toml/panic/panic.stderr b/tests/ui-toml/panic/panic.stderr
index bf7503e086c..a034207d919 100644
--- a/tests/ui-toml/panic/panic.stderr
+++ b/tests/ui-toml/panic/panic.stderr
@@ -1,5 +1,5 @@
 error: `panic` should not be present in production code
-  --> tests/ui-toml/panic/panic.rs:11:14
+  --> tests/ui-toml/panic/panic.rs:12:14
    |
 LL |         _ => panic!(""),
    |              ^^^^^^^^^^
@@ -7,5 +7,11 @@ LL |         _ => panic!(""),
    = note: `-D clippy::panic` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::panic)]`
 
-error: aborting due to 1 previous error
+error: `panic_any` should not be present in production code
+  --> tests/ui-toml/panic/panic.rs:17:5
+   |
+LL |     panic_any("should lint")
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors