]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/dbg_macro.rs
Rollup merge of #91562 - dtolnay:asyncspace, r=Mark-Simulacrum
[rust.git] / src / tools / clippy / clippy_lints / src / dbg_macro.rs
1 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
2 use clippy_utils::source::snippet_opt;
3 use rustc_ast::ast;
4 use rustc_ast::tokenstream::TokenStream;
5 use rustc_errors::Applicability;
6 use rustc_lint::{EarlyContext, EarlyLintPass};
7 use rustc_session::{declare_lint_pass, declare_tool_lint};
8 use rustc_span::source_map::Span;
9
10 declare_clippy_lint! {
11     /// ### What it does
12     /// Checks for usage of dbg!() macro.
13     ///
14     /// ### Why is this bad?
15     /// `dbg!` macro is intended as a debugging tool. It
16     /// should not be in version control.
17     ///
18     /// ### Known problems
19     /// * The lint level is unaffected by crate attributes. The level can still
20     ///   be set for functions, modules and other items. To change the level for
21     ///   the entire crate, please use command line flags. More information and a
22     ///   configuration example can be found in [clippy#6610].
23     ///
24     /// [clippy#6610]: https://github.com/rust-lang/rust-clippy/issues/6610#issuecomment-977120558
25     ///
26     /// ### Example
27     /// ```rust,ignore
28     /// // Bad
29     /// dbg!(true)
30     ///
31     /// // Good
32     /// true
33     /// ```
34     #[clippy::version = "1.34.0"]
35     pub DBG_MACRO,
36     restriction,
37     "`dbg!` macro is intended as a debugging tool"
38 }
39
40 declare_lint_pass!(DbgMacro => [DBG_MACRO]);
41
42 impl EarlyLintPass for DbgMacro {
43     fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
44         if mac.path == sym!(dbg) {
45             if let Some(sugg) = tts_span(mac.args.inner_tokens()).and_then(|span| snippet_opt(cx, span)) {
46                 span_lint_and_sugg(
47                     cx,
48                     DBG_MACRO,
49                     mac.span(),
50                     "`dbg!` macro is intended as a debugging tool",
51                     "ensure to avoid having uses of it in version control",
52                     sugg,
53                     Applicability::MaybeIncorrect,
54                 );
55             } else {
56                 span_lint_and_help(
57                     cx,
58                     DBG_MACRO,
59                     mac.span(),
60                     "`dbg!` macro is intended as a debugging tool",
61                     None,
62                     "ensure to avoid having uses of it in version control",
63                 );
64             }
65         }
66     }
67 }
68
69 // Get span enclosing entire the token stream.
70 fn tts_span(tts: TokenStream) -> Option<Span> {
71     let mut cursor = tts.into_trees();
72     let first = cursor.next()?.span();
73     let span = cursor.last().map_or(first, |tree| first.to(tree.span()));
74     Some(span)
75 }