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 ;
1+ use clippy_utils:: diagnostics:: span_lint_and_sugg;
2+ use clippy_utils:: macros:: root_macro_call_first_node;
3+ use clippy_utils:: source:: snippet_with_applicability;
54use rustc_errors:: Applicability ;
6- use rustc_lint:: { EarlyContext , EarlyLintPass } ;
5+ use rustc_hir:: { Expr , ExprKind } ;
6+ use rustc_lint:: { LateContext , LateLintPass } ;
77use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
8- use rustc_span:: source_map :: Span ;
8+ use rustc_span:: sym ;
99
1010declare_clippy_lint ! {
1111 /// ### What it does
@@ -15,14 +15,6 @@ declare_clippy_lint! {
1515 /// `dbg!` macro is intended as a debugging tool. It
1616 /// should not be in version control.
1717 ///
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- ///
2618 /// ### Example
2719 /// ```rust,ignore
2820 /// // Bad
@@ -39,37 +31,52 @@ declare_clippy_lint! {
3931
4032declare_lint_pass ! ( DbgMacro => [ DBG_MACRO ] ) ;
4133
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- }
34+ impl LateLintPass < ' _ > for DbgMacro {
35+ fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
36+ let Some ( macro_call) = root_macro_call_first_node ( cx, expr) else { return } ;
37+ if cx. tcx . is_diagnostic_item ( sym:: dbg_macro, macro_call. def_id ) {
38+ let mut applicability = Applicability :: MachineApplicable ;
39+ let suggestion = match expr. peel_drop_temps ( ) . kind {
40+ // dbg!()
41+ ExprKind :: Block ( _, _) => String :: new ( ) ,
42+ // dbg!(1)
43+ ExprKind :: Match ( val, ..) => {
44+ snippet_with_applicability ( cx, val. span . source_callsite ( ) , ".." , & mut applicability) . to_string ( )
45+ } ,
46+ // dbg!(2, 3)
47+ ExprKind :: Tup (
48+ [
49+ Expr {
50+ kind : ExprKind :: Match ( first, ..) ,
51+ ..
52+ } ,
53+ ..,
54+ Expr {
55+ kind : ExprKind :: Match ( last, ..) ,
56+ ..
57+ } ,
58+ ] ,
59+ ) => {
60+ let snippet = snippet_with_applicability (
61+ cx,
62+ first. span . source_callsite ( ) . to ( last. span . source_callsite ( ) ) ,
63+ ".." ,
64+ & mut applicability,
65+ ) ;
66+ format ! ( "({snippet})" )
67+ } ,
68+ _ => return ,
69+ } ;
70+
71+ span_lint_and_sugg (
72+ cx,
73+ DBG_MACRO ,
74+ macro_call. span ,
75+ "`dbg!` macro is intended as a debugging tool" ,
76+ "ensure to avoid having uses of it in version control" ,
77+ suggestion,
78+ applicability,
79+ ) ;
6580 }
6681 }
6782}
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- }
0 commit comments