Skip to content

Commit 5735a3b

Browse files
committed
Auto merge of #9259 - smoelius:fix-9256, r=llogiq
Fix `to_string_in_format_args` false positive Fix #9256 changelog: none
2 parents cc637ba + 0bc26c8 commit 5735a3b

File tree

4 files changed

+72
-27
lines changed

4 files changed

+72
-27
lines changed

clippy_lints/src/format_args.rs

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -131,34 +131,45 @@ fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Ex
131131
if is_diag_trait_item(cx, method_def_id, sym::ToString);
132132
let receiver_ty = cx.typeck_results().expr_ty(receiver);
133133
if let Some(display_trait_id) = cx.tcx.get_diagnostic_item(sym::Display);
134+
let (n_needed_derefs, target) =
135+
count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter());
136+
if implements_trait(cx, target, display_trait_id, &[]);
137+
if let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait();
134138
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
135139
then {
136-
let (n_needed_derefs, target) = count_needed_derefs(
137-
receiver_ty,
138-
cx.typeck_results().expr_adjustments(receiver).iter(),
139-
);
140-
if implements_trait(cx, target, display_trait_id, &[]) {
141-
if n_needed_derefs == 0 {
142-
span_lint_and_sugg(
143-
cx,
144-
TO_STRING_IN_FORMAT_ARGS,
145-
value.span.with_lo(receiver.span.hi()),
146-
&format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
147-
"remove this",
148-
String::new(),
149-
Applicability::MachineApplicable,
150-
);
151-
} else {
152-
span_lint_and_sugg(
153-
cx,
154-
TO_STRING_IN_FORMAT_ARGS,
155-
value.span,
156-
&format!("`to_string` applied to a type that implements `Display` in `{}!` args", name),
157-
"use this",
158-
format!("{:*>width$}{}", "", receiver_snippet, width = n_needed_derefs),
159-
Applicability::MachineApplicable,
160-
);
161-
}
140+
let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);
141+
if n_needed_derefs == 0 && !needs_ref {
142+
span_lint_and_sugg(
143+
cx,
144+
TO_STRING_IN_FORMAT_ARGS,
145+
value.span.with_lo(receiver.span.hi()),
146+
&format!(
147+
"`to_string` applied to a type that implements `Display` in `{}!` args",
148+
name
149+
),
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!(
160+
"`to_string` applied to a type that implements `Display` in `{}!` args",
161+
name
162+
),
163+
"use this",
164+
format!(
165+
"{}{:*>width$}{}",
166+
if needs_ref { "&" } else { "" },
167+
"",
168+
receiver_snippet,
169+
width = n_needed_derefs
170+
),
171+
Applicability::MachineApplicable,
172+
);
162173
}
163174
}
164175
}

tests/ui/format_args.fixed

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,17 @@ mod issue_8855 {
146146
dbg!(x);
147147
}
148148
}
149+
150+
// https://github.com/rust-lang/rust-clippy/issues/9256
151+
mod issue_9256 {
152+
#![allow(dead_code)]
153+
154+
fn print_substring(original: &str) {
155+
assert!(original.len() > 10);
156+
println!("{}", &original[..10]);
157+
}
158+
159+
fn main() {
160+
print_substring("Hello, world!");
161+
}
162+
}

tests/ui/format_args.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,17 @@ mod issue_8855 {
146146
dbg!(x);
147147
}
148148
}
149+
150+
// https://github.com/rust-lang/rust-clippy/issues/9256
151+
mod issue_9256 {
152+
#![allow(dead_code)]
153+
154+
fn print_substring(original: &str) {
155+
assert!(original.len() > 10);
156+
println!("{}", original[..10].to_string());
157+
}
158+
159+
fn main() {
160+
print_substring("Hello, world!");
161+
}
162+
}

tests/ui/format_args.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,11 @@ error: `to_string` applied to a type that implements `Display` in `format!` args
132132
LL | let x = format!("{} {}", a, b.to_string());
133133
| ^^^^^^^^^^^^ help: remove this
134134

135-
error: aborting due to 22 previous errors
135+
error: `to_string` applied to a type that implements `Display` in `println!` args
136+
--> $DIR/format_args.rs:156:24
137+
|
138+
LL | println!("{}", original[..10].to_string());
139+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
140+
141+
error: aborting due to 23 previous errors
136142

0 commit comments

Comments
 (0)