about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2022-01-15 14:33:43 -0500
committerJason Newcomb <jsnewcomb@pm.me>2022-01-15 16:28:49 -0500
commitcb384ff03b7a10bca10b962d9907c0d56ba3086f (patch)
tree43b06826803b26541e83bb9b84db1cb81d7e9f7e
parent496f26c2297c0117a24c3d26172fd72b5f9ad927 (diff)
downloadrust-cb384ff03b7a10bca10b962d9907c0d56ba3086f.tar.gz
rust-cb384ff03b7a10bca10b962d9907c0d56ba3086f.zip
Handle implicit named arguments in `useless_format`
-rw-r--r--clippy_lints/src/format.rs19
-rw-r--r--tests/ui/format.fixed6
-rw-r--r--tests/ui/format.rs6
-rw-r--r--tests/ui/format.stderr14
4 files changed, 42 insertions, 3 deletions
diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs
index 688d8f8630f..395c920c997 100644
--- a/clippy_lints/src/format.rs
+++ b/clippy_lints/src/format.rs
@@ -9,7 +9,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Span};
+use rustc_span::{sym, BytePos, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -84,7 +84,22 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
                         ExprKind::MethodCall(path, ..) => path.ident.name.as_str() == "to_string",
                         _ => false,
                     };
-                    let sugg = if is_new_string {
+                    let sugg = if format_args.format_string_span.contains(value.span) {
+                        // Implicit argument. e.g. `format!("{x}")` span points to `{x}`
+                        let spdata = value.span.data();
+                        let span = Span::new(
+                            spdata.lo + BytePos(1),
+                            spdata.hi - BytePos(1),
+                            spdata.ctxt,
+                            spdata.parent
+                        );
+                        let snip = snippet_with_applicability(cx, span, "..", &mut applicability);
+                        if is_new_string {
+                            snip.into()
+                        } else {
+                            format!("{snip}.to_string()")
+                        }
+                    } else if is_new_string {
                         snippet_with_applicability(cx, value.span, "..", &mut applicability).into_owned()
                     } else {
                         let sugg = Sugg::hir_with_applicability(cx, value, "<arg>", &mut applicability);
diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed
index 64cb7b1cfb8..78d2bfd474e 100644
--- a/tests/ui/format.fixed
+++ b/tests/ui/format.fixed
@@ -73,4 +73,10 @@ fn main() {
     let _s: String = (&*v.join("\n")).to_string();
 
     format!("prepend {:+}", "s");
+
+    // Issue #8290
+    let x = "foo";
+    let _ = x.to_string();
+    let _ = format!("{x:?}"); // Don't lint on debug
+    let _ = x.to_string();
 }
diff --git a/tests/ui/format.rs b/tests/ui/format.rs
index a065b1b5683..009c1aa216f 100644
--- a/tests/ui/format.rs
+++ b/tests/ui/format.rs
@@ -75,4 +75,10 @@ fn main() {
     let _s: String = format!("{}", &*v.join("\n"));
 
     format!("prepend {:+}", "s");
+
+    // Issue #8290
+    let x = "foo";
+    let _ = format!("{x}");
+    let _ = format!("{x:?}"); // Don't lint on debug
+    let _ = format!("{y}", y = x);
 }
diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr
index 58ad7499bb2..660be57585e 100644
--- a/tests/ui/format.stderr
+++ b/tests/ui/format.stderr
@@ -99,5 +99,17 @@ error: useless use of `format!`
 LL |     let _s: String = format!("{}", &*v.join("/n"));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
 
-error: aborting due to 15 previous errors
+error: useless use of `format!`
+  --> $DIR/format.rs:81:13
+   |
+LL |     let _ = format!("{x}");
+   |             ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
+
+error: useless use of `format!`
+  --> $DIR/format.rs:83:13
+   |
+LL |     let _ = format!("{y}", y = x);
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
+
+error: aborting due to 17 previous errors