|
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,16 @@ 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.has_string_formatting() { |
81 | 81 | continue;
|
82 | 82 | }
|
83 |
| - if arg.has_string_formatting() { |
| 83 | + if is_aliased(&format_args, arg.param.value.hir_id) { |
84 | 84 | continue;
|
85 | 85 | }
|
86 |
| - if is_aliased(&args, i) { |
87 |
| - continue; |
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); |
| 86 | + check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value); |
| 87 | + check_to_string_in_format_args(cx, name, arg.param.value); |
91 | 88 | }
|
92 | 89 | }
|
93 | 90 | }
|
@@ -167,12 +164,12 @@ fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Ex
|
167 | 164 | }
|
168 | 165 | }
|
169 | 166 |
|
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)) |
| 167 | +// Returns true if `hir_id` is referred to by multiple format params |
| 168 | +fn is_aliased(args: &FormatArgsExpn<'_>, hir_id: HirId) -> bool { |
| 169 | + args.params() |
| 170 | + .filter(|param| param.value.hir_id == hir_id) |
| 171 | + .at_most_one() |
| 172 | + .is_err() |
176 | 173 | }
|
177 | 174 |
|
178 | 175 | fn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>)
|
|
0 commit comments