@@ -17,7 +17,9 @@ use clippy_utils::macros::{
17
17
find_format_arg_expr, find_format_args, is_format_macro, macro_backtrace,
18
18
} ;
19
19
use clippy_utils:: ty:: implements_trait;
20
- use clippy_utils:: { is_in_cfg_test, is_in_test_function, is_trait_method, match_function_call} ;
20
+ use clippy_utils:: {
21
+ is_in_cfg_test, is_in_test_function, is_trait_method, match_def_path, match_function_call,
22
+ } ;
21
23
use rustc_ast:: FormatArgsPiece ;
22
24
use rustc_hir:: { Expr , ExprKind } ;
23
25
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -60,6 +62,7 @@ impl_lint_pass!(FormatError => [FORMAT_ERROR]);
60
62
61
63
const TRACING_FIELD_DEBUG : [ & str ; 3 ] = [ "tracing_core" , "field" , "debug" ] ;
62
64
const TRACING_FIELD_DISPLAY : [ & str ; 3 ] = [ "tracing_core" , "field" , "display" ] ;
65
+ const TRACING_MACRO_EVENT : [ & str ; 3 ] = [ "tracing" , "macros" , "event" ] ;
63
66
64
67
impl < ' tcx > LateLintPass < ' tcx > for FormatError {
65
68
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
@@ -77,6 +80,9 @@ impl<'tcx> LateLintPass<'tcx> for FormatError {
77
80
}
78
81
79
82
// `{}`, `{:?}` in format macros.
83
+ let in_tracing_macro_event = macro_backtrace ( expr. span )
84
+ . any ( |macro_call| match_def_path ( cx, macro_call. def_id , & TRACING_MACRO_EVENT ) ) ;
85
+
80
86
for macro_call in macro_backtrace ( expr. span ) {
81
87
if is_format_macro ( cx, macro_call. def_id )
82
88
&& let Some ( format_args) = find_format_args ( cx, expr, macro_call. expn )
@@ -87,7 +93,11 @@ impl<'tcx> LateLintPass<'tcx> for FormatError {
87
93
&& let Some ( arg) = format_args. arguments . all_args ( ) . get ( index)
88
94
&& let Ok ( arg_expr) = find_format_arg_expr ( expr, arg)
89
95
{
90
- check_fmt_arg ( cx, arg_expr) ;
96
+ if in_tracing_macro_event {
97
+ check_fmt_arg_in_tracing_event ( cx, arg_expr) ;
98
+ } else {
99
+ check_fmt_arg ( cx, arg_expr) ;
100
+ }
91
101
}
92
102
}
93
103
}
@@ -111,6 +121,17 @@ fn check_fmt_arg(cx: &LateContext<'_>, arg_expr: &Expr<'_>) {
111
121
) ;
112
122
}
113
123
124
+ fn check_fmt_arg_in_tracing_event ( cx : & LateContext < ' _ > , arg_expr : & Expr < ' _ > ) {
125
+ // TODO: replace `<error>` with the actual code snippet.
126
+ check_arg (
127
+ cx,
128
+ arg_expr,
129
+ arg_expr. span ,
130
+ "consider importing `thiserror_ext::AsReport` and recording the error as a field
131
+ with `error = %<error>.as_report()` instead" ,
132
+ ) ;
133
+ }
134
+
114
135
fn check_to_string_call ( cx : & LateContext < ' _ > , receiver : & Expr < ' _ > , to_string_span : Span ) {
115
136
check_arg (
116
137
cx,
0 commit comments