]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/dbg_macro.rs
Rollup merge of #94868 - dtolnay:noblock, r=Dylan-DPC
[rust.git] / src / tools / clippy / clippy_lints / src / dbg_macro.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::is_in_test_function;
3 use clippy_utils::macros::root_macro_call_first_node;
4 use clippy_utils::source::snippet_with_applicability;
5 use rustc_errors::Applicability;
6 use rustc_hir::{Expr, ExprKind};
7 use rustc_lint::{LateContext, LateLintPass};
8 use rustc_session::{declare_lint_pass, declare_tool_lint};
9 use rustc_span::sym;
10
11 declare_clippy_lint! {
12     /// ### What it does
13     /// Checks for usage of dbg!() macro.
14     ///
15     /// ### Why is this bad?
16     /// `dbg!` macro is intended as a debugging tool. It
17     /// should not be in version control.
18     ///
19     /// ### Example
20     /// ```rust,ignore
21     /// // Bad
22     /// dbg!(true)
23     ///
24     /// // Good
25     /// true
26     /// ```
27     #[clippy::version = "1.34.0"]
28     pub DBG_MACRO,
29     restriction,
30     "`dbg!` macro is intended as a debugging tool"
31 }
32
33 declare_lint_pass!(DbgMacro => [DBG_MACRO]);
34
35 impl LateLintPass<'_> for DbgMacro {
36     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
37         let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
38         if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) {
39             // we make an exception for test code
40             if is_in_test_function(cx.tcx, expr.hir_id) {
41                 return;
42             }
43             let mut applicability = Applicability::MachineApplicable;
44             let suggestion = match expr.peel_drop_temps().kind {
45                 // dbg!()
46                 ExprKind::Block(_, _) => String::new(),
47                 // dbg!(1)
48                 ExprKind::Match(val, ..) => {
49                     snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability).to_string()
50                 },
51                 // dbg!(2, 3)
52                 ExprKind::Tup(
53                     [
54                         Expr {
55                             kind: ExprKind::Match(first, ..),
56                             ..
57                         },
58                         ..,
59                         Expr {
60                             kind: ExprKind::Match(last, ..),
61                             ..
62                         },
63                     ],
64                 ) => {
65                     let snippet = snippet_with_applicability(
66                         cx,
67                         first.span.source_callsite().to(last.span.source_callsite()),
68                         "..",
69                         &mut applicability,
70                     );
71                     format!("({snippet})")
72                 },
73                 _ => return,
74             };
75
76             span_lint_and_sugg(
77                 cx,
78                 DBG_MACRO,
79                 macro_call.span,
80                 "`dbg!` macro is intended as a debugging tool",
81                 "ensure to avoid having uses of it in version control",
82                 suggestion,
83                 applicability,
84             );
85         }
86     }
87 }