Skip to content

Commit

Permalink
Make useless_format recognize format!("")
Browse files Browse the repository at this point in the history
Closes #7796
  • Loading branch information
aDotInTheVoid committed Oct 11, 2021
1 parent 9205e3d commit 74c2a4d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 19 deletions.
39 changes: 30 additions & 9 deletions clippy_lints/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,19 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {

let mut applicability = Applicability::MachineApplicable;
if format_args.value_args.is_empty() {
if_chain! {
if let [e] = &*format_args.format_string_parts;
if let ExprKind::Lit(lit) = &e.kind;
if let Some(s_src) = snippet_opt(cx, lit.span);
then {
// Simulate macro expansion, converting {{ and }} to { and }.
let s_expand = s_src.replace("{{", "{").replace("}}", "}");
let sugg = format!("{}.to_string()", s_expand);
span_useless_format(cx, call_site, sugg, applicability);
if format_args.format_string_parts.is_empty() {
span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability);
} else {
if_chain! {
if let [e] = &*format_args.format_string_parts;
if let ExprKind::Lit(lit) = &e.kind;
if let Some(s_src) = snippet_opt(cx, lit.span);
then {
// Simulate macro expansion, converting {{ and }} to { and }.
let s_expand = s_src.replace("{{", "{").replace("}}", "}");
let sugg = format!("{}.to_string()", s_expand);
span_useless_format(cx, call_site, sugg, applicability);
}
}
}
} else if let [value] = *format_args.value_args {
Expand Down Expand Up @@ -90,6 +94,23 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
}
}

fn span_useless_format_empty(cx: &LateContext<'_>, span: Span, mut sugg: String, mut applicability: Applicability) {
// The callsite span contains the statement semicolon for some reason.
if snippet_with_applicability(cx, span, "..", &mut applicability).ends_with(';') {
sugg.push(';');
}

span_lint_and_sugg(
cx,
USELESS_FORMAT,
span,
"useless use of `format!`",
"consider using `String::new()`",
sugg,
applicability,
);
}

fn span_useless_format(cx: &LateContext<'_>, span: Span, mut sugg: String, mut applicability: Applicability) {
// The callsite span contains the statement semicolon for some reason.
if snippet_with_applicability(cx, span, "..", &mut applicability).ends_with(';') {
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/format.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ fn main() {
r##"foo {}
" bar"##.to_string();

String::new();

"foo".to_string();
format!("{:?}", "foo"); // Don't warn about `Debug`.
format!("{:8}", "foo");
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ fn main() {
" bar"##
);

format!("");

format!("{}", "foo");
format!("{:?}", "foo"); // Don't warn about `Debug`.
format!("{:8}", "foo");
Expand Down
26 changes: 16 additions & 10 deletions tests/ui/format.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -36,62 +36,68 @@ LL + " bar"##.to_string();
error: useless use of `format!`
--> $DIR/format.rs:21:5
|
LL | format!("");
| ^^^^^^^^^^^^ help: consider using `String::new()`: `String::new();`

error: useless use of `format!`
--> $DIR/format.rs:23:5
|
LL | format!("{}", "foo");
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string();`

error: useless use of `format!`
--> $DIR/format.rs:25:5
--> $DIR/format.rs:27:5
|
LL | format!("{:+}", "foo"); // Warn when the format makes no difference.
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string();`

error: useless use of `format!`
--> $DIR/format.rs:26:5
--> $DIR/format.rs:28:5
|
LL | format!("{:<}", "foo"); // Warn when the format makes no difference.
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string();`

error: useless use of `format!`
--> $DIR/format.rs:31:5
--> $DIR/format.rs:33:5
|
LL | format!("{}", arg);
| ^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string();`

error: useless use of `format!`
--> $DIR/format.rs:35:5
--> $DIR/format.rs:37:5
|
LL | format!("{:+}", arg); // Warn when the format makes no difference.
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string();`

error: useless use of `format!`
--> $DIR/format.rs:36:5
--> $DIR/format.rs:38:5
|
LL | format!("{:<}", arg); // Warn when the format makes no difference.
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string();`

error: useless use of `format!`
--> $DIR/format.rs:63:5
--> $DIR/format.rs:65:5
|
LL | format!("{}", 42.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string();`

error: useless use of `format!`
--> $DIR/format.rs:65:5
--> $DIR/format.rs:67:5
|
LL | format!("{}", x.display().to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string();`

error: useless use of `format!`
--> $DIR/format.rs:69:18
--> $DIR/format.rs:71:18
|
LL | let _ = Some(format!("{}", a + "bar"));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`

error: useless use of `format!`
--> $DIR/format.rs:73:22
--> $DIR/format.rs:75:22
|
LL | let _s: String = format!("{}", &*v.join("/n"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`

error: aborting due to 14 previous errors
error: aborting due to 15 previous errors

0 comments on commit 74c2a4d

Please sign in to comment.