Skip to content

Commit 41309df

Browse files
committed
Auto merge of rust-lang#8857 - smoelius:fix-8855, r=flip1995
Add test for rust-lang#8855 Fix rust-lang#8855 Here is what I think is going on. First, the expression `format!("{:>6} {:>6}", a, b.to_string())` expands to: ```rust { let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1_formatted(&["", " "], &[::core::fmt::ArgumentV1::new_display(&a), ::core::fmt::ArgumentV1::new_display(&b.to_string())], &[::core::fmt::rt::v1::Argument { position: 0usize, format: ::core::fmt::rt::v1::FormatSpec { fill: ' ', align: ::core::fmt::rt::v1::Alignment::Right, flags: 0u32, precision: ::core::fmt::rt::v1::Count::Implied, width: ::core::fmt::rt::v1::Count::Is(6usize), }, }, ::core::fmt::rt::v1::Argument { position: 1usize, format: ::core::fmt::rt::v1::FormatSpec { fill: ' ', align: ::core::fmt::rt::v1::Alignment::Right, flags: 0u32, precision: ::core::fmt::rt::v1::Count::Implied, width: ::core::fmt::rt::v1::Count::Is(6usize), }, }], unsafe { ::core::fmt::UnsafeArg::new() })); res } ``` When I dump the expressions that get past the call to `has_string_formatting` [here](https://github.com/rust-lang/rust-clippy/blob/b312ad7d0cf0f30be2bd4658b71a3520a2e76709/clippy_lints/src/format_args.rs#L83), I see more than I would expect. In particular, I see this subexpression of the above: ``` &[::core::fmt::ArgumentV1::new_display(&a), ::core::fmt::ArgumentV1::new_display(&b.to_string())], ``` This suggests to me that more expressions are getting past [this call](https://github.com/rust-lang/rust-clippy/blob/b312ad7d0cf0f30be2bd4658b71a3520a2e76709/clippy_lints/src/format_args.rs#L71) to `FormatArgsExpn::parse` than should. Those expressions are then visited, but no `::core::fmt::rt::v1::Argument`s are found and pushed [here](https://github.com/rust-lang/rust-clippy/blob/b312ad7d0cf0f30be2bd4658b71a3520a2e76709/clippy_utils/src/macros.rs#L407). As a result, the expressions appear unformatted, hence, the false positive. My proposed fix is to restrict `FormatArgsExpn::parse` so that it only matches `Call` expressions. cc: `@akanalytics` changelog: none
2 parents 5820add + 6f3d398 commit 41309df

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

tests/ui/format_args.fixed

+24
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,27 @@ fn issue8643(vendor_id: usize, product_id: usize, name: &str) {
122122
name
123123
);
124124
}
125+
126+
// https://github.com/rust-lang/rust-clippy/issues/8855
127+
mod issue_8855 {
128+
#![allow(dead_code)]
129+
130+
struct A {}
131+
132+
impl std::fmt::Display for A {
133+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
134+
write!(f, "test")
135+
}
136+
}
137+
138+
fn main() {
139+
let a = A {};
140+
let b = A {};
141+
142+
let x = format!("{} {}", a, b);
143+
dbg!(x);
144+
145+
let x = format!("{:>6} {:>6}", a, b.to_string());
146+
dbg!(x);
147+
}
148+
}

tests/ui/format_args.rs

+24
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,27 @@ fn issue8643(vendor_id: usize, product_id: usize, name: &str) {
122122
name
123123
);
124124
}
125+
126+
// https://github.com/rust-lang/rust-clippy/issues/8855
127+
mod issue_8855 {
128+
#![allow(dead_code)]
129+
130+
struct A {}
131+
132+
impl std::fmt::Display for A {
133+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
134+
write!(f, "test")
135+
}
136+
}
137+
138+
fn main() {
139+
let a = A {};
140+
let b = A {};
141+
142+
let x = format!("{} {}", a, b.to_string());
143+
dbg!(x);
144+
145+
let x = format!("{:>6} {:>6}", a, b.to_string());
146+
dbg!(x);
147+
}
148+
}

tests/ui/format_args.stderr

+7-1
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 `format!` args
130+
--> $DIR/format_args.rs:142:38
131+
|
132+
LL | let x = format!("{} {}", a, b.to_string());
133+
| ^^^^^^^^^^^^ help: remove this
134+
135+
error: aborting due to 22 previous errors
130136

0 commit comments

Comments
 (0)