Skip to content

Commit c62cafc

Browse files
committed
Fix to_string_in_format_args false positive
1 parent 70bca29 commit c62cafc

File tree

4 files changed

+76
-27
lines changed

4 files changed

+76
-27
lines changed

clippy_lints/src/format_args.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -134,34 +134,49 @@ fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Ex
134134
if is_diag_trait_item(cx, method_def_id, sym::ToString);
135135
let receiver_ty = cx.typeck_results().expr_ty(receiver);
136136
if let Some(display_trait_id) = cx.tcx.get_diagnostic_item(sym::Display);
137+
let (n_needed_derefs, target) =
138+
count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter());
139+
if implements_trait(cx, target, display_trait_id, &[]);
140+
if let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait();
137141
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
138142
then {
139-
let (n_needed_derefs, target) = count_needed_derefs(
140-
receiver_ty,
141-
cx.typeck_results().expr_adjustments(receiver).iter(),
142-
);
143-
if implements_trait(cx, target, display_trait_id, &[]) {
144-
if n_needed_derefs == 0 {
145-
span_lint_and_sugg(
146-
cx,
147-
TO_STRING_IN_FORMAT_ARGS,
148-
value.span.with_lo(receiver.span.hi()),
149-
&format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
150-
"remove this",
151-
String::new(),
152-
Applicability::MachineApplicable,
153-
);
154-
} else {
155-
span_lint_and_sugg(
156-
cx,
157-
TO_STRING_IN_FORMAT_ARGS,
158-
value.span,
159-
&format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
160-
"use this",
161-
format!("{:*>width$}{}", "", receiver_snippet, width = n_needed_derefs),
162-
Applicability::MachineApplicable,
163-
);
164-
}
143+
let needed_ref = if implements_trait(cx, receiver_ty, sized_trait_id, &[]) {
144+
""
145+
} else {
146+
"&"
147+
};
148+
if n_needed_derefs == 0 && needed_ref.is_empty() {
149+
span_lint_and_sugg(
150+
cx,
151+
TO_STRING_IN_FORMAT_ARGS,
152+
value.span.with_lo(receiver.span.hi()),
153+
&format!(
154+
"`to_string` applied to a type that implements `Display` in `{}!` args",
155+
name
156+
),
157+
"remove this",
158+
String::new(),
159+
Applicability::MachineApplicable,
160+
);
161+
} else {
162+
span_lint_and_sugg(
163+
cx,
164+
TO_STRING_IN_FORMAT_ARGS,
165+
value.span,
166+
&format!(
167+
"`to_string` applied to a type that implements `Display` in `{}!` args",
168+
name
169+
),
170+
"use this",
171+
format!(
172+
"{}{:*>width$}{}",
173+
needed_ref,
174+
"",
175+
receiver_snippet,
176+
width = n_needed_derefs
177+
),
178+
Applicability::MachineApplicable,
179+
);
165180
}
166181
}
167182
}

tests/ui/format_args.fixed

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,17 @@ fn main() {
115115
// https://github.com/rust-lang/rust-clippy/issues/7903
116116
println!("{foo}{foo:?}", foo = "foo".to_string());
117117
}
118+
119+
// https://github.com/rust-lang/rust-clippy/issues/9256
120+
mod issue_9256 {
121+
#![allow(dead_code)]
122+
123+
fn print_substring(original: &str) {
124+
assert!(original.len() > 10);
125+
println!("{}", &original[..10]);
126+
}
127+
128+
fn main() {
129+
print_substring("Hello, world!");
130+
}
131+
}

tests/ui/format_args.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,17 @@ fn main() {
115115
// https://github.com/rust-lang/rust-clippy/issues/7903
116116
println!("{foo}{foo:?}", foo = "foo".to_string());
117117
}
118+
119+
// https://github.com/rust-lang/rust-clippy/issues/9256
120+
mod issue_9256 {
121+
#![allow(dead_code)]
122+
123+
fn print_substring(original: &str) {
124+
assert!(original.len() > 10);
125+
println!("{}", original[..10].to_string());
126+
}
127+
128+
fn main() {
129+
print_substring("Hello, world!");
130+
}
131+
}

tests/ui/format_args.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,11 @@ error: `to_string` applied to a type that implements `Display` in `println!` arg
126126
LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
127127
| ^^^^^^^^^^^^ help: remove this
128128

129-
error: aborting due to 21 previous errors
129+
error: `to_string` applied to a type that implements `Display` in `println!` args
130+
--> $DIR/format_args.rs:125:24
131+
|
132+
LL | println!("{}", original[..10].to_string());
133+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
134+
135+
error: aborting due to 22 previous errors
130136

0 commit comments

Comments
 (0)