|
1 | 1 | use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; |
2 | 2 | use clippy_utils::is_diag_trait_item; |
3 | | -use clippy_utils::macros::{is_format_macro, FormatArgsArg, FormatArgsExpn}; |
| 3 | +use clippy_utils::macros::{is_format_macro, FormatArgsExpn}; |
4 | 4 | use clippy_utils::source::snippet_opt; |
5 | 5 | use clippy_utils::ty::implements_trait; |
6 | 6 | use if_chain::if_chain; |
| 7 | +use itertools::Itertools; |
7 | 8 | use rustc_errors::Applicability; |
8 | | -use rustc_hir::{Expr, ExprKind}; |
| 9 | +use rustc_hir::{Expr, ExprKind, HirId}; |
9 | 10 | use rustc_lint::{LateContext, LateLintPass}; |
10 | 11 | use rustc_middle::ty::adjustment::{Adjust, Adjustment}; |
11 | 12 | use rustc_middle::ty::Ty; |
@@ -74,20 +75,19 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs { |
74 | 75 | if let Some(macro_def_id) = outermost_expn_data.macro_def_id; |
75 | 76 | if is_format_macro(cx, macro_def_id); |
76 | 77 | if let ExpnKind::Macro(_, name) = outermost_expn_data.kind; |
77 | | - if let Some(args) = format_args.args(); |
78 | 78 | then { |
79 | | - for (i, arg) in args.iter().enumerate() { |
80 | | - if arg.format_trait != sym::Display { |
| 79 | + for arg in &format_args.args { |
| 80 | + if arg.format.r#trait != sym::Display { |
81 | 81 | continue; |
82 | 82 | } |
83 | | - if arg.has_string_formatting() { |
| 83 | + if arg.format.has_string_formatting() { |
84 | 84 | continue; |
85 | 85 | } |
86 | | - if is_aliased(&args, i) { |
| 86 | + if is_aliased(&format_args, arg.param.value.hir_id) { |
87 | 87 | continue; |
88 | 88 | } |
89 | | - check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.value); |
90 | | - check_to_string_in_format_args(cx, name, arg.value); |
| 89 | + check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value); |
| 90 | + check_to_string_in_format_args(cx, name, arg.param.value); |
91 | 91 | } |
92 | 92 | } |
93 | 93 | } |
@@ -167,12 +167,12 @@ fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Ex |
167 | 167 | } |
168 | 168 | } |
169 | 169 |
|
170 | | -// Returns true if `args[i]` "refers to" or "is referred to by" another argument. |
171 | | -fn is_aliased(args: &[FormatArgsArg<'_>], i: usize) -> bool { |
172 | | - let value = args[i].value; |
173 | | - args.iter() |
174 | | - .enumerate() |
175 | | - .any(|(j, arg)| i != j && std::ptr::eq(value, arg.value)) |
| 170 | +// Returns true if `hir_id` is referred to by multiple format params |
| 171 | +fn is_aliased(args: &FormatArgsExpn<'_>, hir_id: HirId) -> bool { |
| 172 | + args.params() |
| 173 | + .filter(|param| param.value.hir_id == hir_id) |
| 174 | + .at_most_one() |
| 175 | + .is_err() |
176 | 176 | } |
177 | 177 |
|
178 | 178 | fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>) |
|
0 commit comments