Description
Summary
clippy::print_literal
and clippy::write_literal
warn about using a literal as an argument to the formatting macros. Instead, such literals can be inlined directly into the format string, which is more efficient.
These warnings generate a suggested fix which does this inlining. However, they perform escaping incorrectly when constructing the new suggested format string, leading to incorrect code. Braces are both part of the underlying string literal language level syntax, and part of the library level formatting string syntax, and the suggested fix does not correctly handle the interaction between these two different uses of brace characters in the source code.
Reproducer
I tried this code:
fn main() {
use std::io::Write;
println!("{}", "\u{1F980}");
writeln!(std::io::stdout(), "{}", "\u{1F980}").ok();
}
I expected to see this happen:
- Correct fixes suggested to replace the use of a literal as a formatted argument (on writeln! and println!).
Instead, this happened:
- Incorrect fixes were suggested. In particular, note that the suggested fix sets the format string to
"\u{{1F980}}"
. This is wrong, because the braces are part of the Unicode character escape sequence in the string, not part of the format string that is parsed by the std formatting machinery, hence they should not be doubled as they are in the Clippy-suggested fix.
warning: literal with an empty format string
--> src/main.rs:3:20
|
3 | println!("{}", "\u{1F980}");
| ^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#print_literal
= note: `#[warn(clippy::print_literal)]` on by default
help: try this
|
3 - println!("{}", "\u{1F980}");
3 + println!("\u{{1F980}}");
|
warning: literal with an empty format string
--> src/main.rs:4:39
|
4 | writeln!(std::io::stdout(), "{}", "\u{1F980}").ok();
| ^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#write_literal
= note: `#[warn(clippy::write_literal)]` on by default
help: try this
|
4 - writeln!(std::io::stdout(), "{}", "\u{1F980}").ok();
4 + writeln!(std::io::stdout(), "\u{{1F980}}").ok();
|
Version
No response
Additional Labels
No response