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;
5
4
use rustc_errors:: Applicability ;
6
- use rustc_lint:: { EarlyContext , EarlyLintPass } ;
5
+ use rustc_hir:: { Expr , ExprKind } ;
6
+ use rustc_lint:: { LateContext , LateLintPass } ;
7
7
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
8
- use rustc_span:: source_map :: Span ;
8
+ use rustc_span:: sym ;
9
9
10
10
declare_clippy_lint ! {
11
11
/// ### What it does
@@ -15,14 +15,6 @@ declare_clippy_lint! {
15
15
/// `dbg!` macro is intended as a debugging tool. It
16
16
/// should not be in version control.
17
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
18
/// ### Example
27
19
/// ```rust,ignore
28
20
/// // Bad
@@ -39,37 +31,52 @@ declare_clippy_lint! {
39
31
40
32
declare_lint_pass ! ( DbgMacro => [ DBG_MACRO ] ) ;
41
33
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
+ ) ;
65
80
}
66
81
}
67
82
}
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