Clippy lints / Pedantic
Clippy lint · Pedantic · checked with Clippy 0.1.99
clippy::format_push_string: `format!(..)` appended to existing `String`
What it meansDetects cases where the result of a format! call is appended to an existing String. It is in the pedantic group and off by default.
What you see
warning: `format!(..)` appended to existing `String` --> main.rs:4:1 | 4 | s += &format!("0x{:X}", 1024); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: you may need to import the `std::fmt::Write` trait = help: for further information visit https://rust-lang.github.io/rust-clippy/stable/index.html#format_push_string = note: `-W clippy::format-push-string` implied by `-W clippy::pedantic` help: consider using `write!` to avoid the extra allocation | 4 - s += &format!("0x{:X}", 1024); 4 + let _ = write!(s, "0x{:X}", 1024); |
Real output of Clippy 0.1.99 (Rust 1.99) on the example below. Names and line numbers in yours will differ.
Does it matter?
Introduces an extra, avoidable heap allocation.
Stricter lints with some false positives. Off by default; opt in with clippy::pedantic.
How to fix it
Clippy does not fix this one automatically (its suggestion may change behaviour, so it only shows it). Change the code by hand:
Flagged
let mut s = String::new();
s += &format!("0x{:X}", 1024);
s.push_str(&format!("0x{:X}", 1024));
Write this instead
use std::fmt::Write as _; // import without risk of name clashing
let mut s = String::new();
let _ = write!(s, "0x{:X}", 1024);
Turn it off, or on
It is off by default. To use it, set it to warn or deny:
Whole crate (Cargo.toml)
[lints.clippy]
format_push_string = "warn"In code
#![warn(clippy::format_push_string)]One run
cargo clippy -- -W clippy::format-push-stringThe [lints] table needs Rust 1.74 or newer. In a workspace, put it under [workspace.lints.clippy] and add [lints] workspace = true to each member.
Clippy's own documentation
What it does
Detects cases where the result of a format! call is
appended to an existing String.
Why is this bad?
Introduces an extra, avoidable heap allocation.
Known problems
format! returns a String but write! returns a Result.
Thus you are forced to ignore the Err variant to achieve the same API.
While using write! in the suggested way should never fail, this isn’t necessarily clear to the programmer.
Example
let mut s = String::new();
s += &format!("0x{:X}", 1024);
s.push_str(&format!("0x{:X}", 1024));
Use instead:
use std::fmt::Write as _; // import without risk of name clashing
let mut s = String::new();
let _ = write!(s, "0x{:X}", 1024);
From the Clippy lint list (0.1.99), part of the Rust project, MIT or Apache-2.0. Official entry.
Related lints
- too_many_linesChecks for functions with a large amount of lines
- missing_errors_docChecks the doc comments of publicly visible functions that return a Result type and warns if there is no # Errors section
- must_use_candidateChecks for public functions that have no #[must_use] attribute, but return something not already marked must-use, have no mutable arg and mutate no statics
- float_cmpstrict comparison of `f32` or `f64`
- fn_params_excessive_boolsChecks for excessive use of bools in function declarations
- format_collectuse of `format!` to build up a string from an iterator
- if_not_elseChecks for usage of ! or != in an if condition with an else branch
- ignore_without_reasonChecks for ignored tests without messages
- ignored_unit_patternsmatching over `()` is more explicit
All 847 Clippy lints · Rust compiler errors · Cargo.toml checker
Up next
Related lintclippy::too_many_linesChecks for functions with a large amount of linesRead it next →Did this answer your question?