about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/literal_string_with_formatting_arg.rs47
-rw-r--r--tests/ui/literal_string_with_formatting_arg.rs6
-rw-r--r--tests/ui/literal_string_with_formatting_arg.stderr34
3 files changed, 49 insertions, 38 deletions
diff --git a/clippy_lints/src/literal_string_with_formatting_arg.rs b/clippy_lints/src/literal_string_with_formatting_arg.rs
index e72f0de90c6..2938ff3772f 100644
--- a/clippy_lints/src/literal_string_with_formatting_arg.rs
+++ b/clippy_lints/src/literal_string_with_formatting_arg.rs
@@ -70,31 +70,40 @@ impl EarlyLintPass for LiteralStringWithFormattingArg {
                         continue;
                     }
 
-                    let mut end = fmt_str[pos.end..].find('}').map_or(pos.end, |found| found + pos.end);
-                    if fmt_str[start..end].contains(':') {
-                        end += 1;
+                    if fmt_str[start + 1..].trim_start().starts_with('}') {
+                        // For now, we ignore `{}`.
+                        continue;
                     }
+
+                    let end = fmt_str[start + 1..]
+                        .find('}')
+                        .map_or(pos.end, |found| start + 1 + found)
+                        + 1;
                     spans.push(
                         expr.span
-                            .with_hi(lo + BytePos((start + add) as _))
-                            .with_lo(lo + BytePos((end + add) as _)),
+                            .with_hi(lo + BytePos((start + add).try_into().unwrap()))
+                            .with_lo(lo + BytePos((end + add).try_into().unwrap())),
                     );
                 }
             }
-            if spans.len() == 1 {
-                span_lint(
-                    cx,
-                    LITERAL_STRING_WITH_FORMATTING_ARG,
-                    spans,
-                    "this looks like a formatting argument but it is not part of a formatting macro",
-                );
-            } else if spans.len() > 1 {
-                span_lint(
-                    cx,
-                    LITERAL_STRING_WITH_FORMATTING_ARG,
-                    spans,
-                    "these look like formatting arguments but are not part of a formatting macro",
-                );
+            match spans.len() {
+                0 => {},
+                1 => {
+                    span_lint(
+                        cx,
+                        LITERAL_STRING_WITH_FORMATTING_ARG,
+                        spans,
+                        "this looks like a formatting argument but it is not part of a formatting macro",
+                    );
+                },
+                _ => {
+                    span_lint(
+                        cx,
+                        LITERAL_STRING_WITH_FORMATTING_ARG,
+                        spans,
+                        "these look like formatting arguments but are not part of a formatting macro",
+                    );
+                },
             }
         }
     }
diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs
index 539d24efe7c..d623ab524fb 100644
--- a/tests/ui/literal_string_with_formatting_arg.rs
+++ b/tests/ui/literal_string_with_formatting_arg.rs
@@ -5,6 +5,7 @@ fn main() {
     let x: Option<usize> = None;
     let y = "hello";
     x.expect("{y} {}"); //~ literal_string_with_formatting_arg
+    x.expect(" {y} bla"); //~ literal_string_with_formatting_arg
     x.expect("{:?}"); //~ literal_string_with_formatting_arg
     x.expect("{y:?}"); //~ literal_string_with_formatting_arg
     x.expect(" {y:?} {y:?} "); //~ literal_string_with_formatting_arg
@@ -12,13 +13,14 @@ fn main() {
     x.expect(r"{y:?}  {y:?} "); //~ literal_string_with_formatting_arg
     x.expect(r"{y:?} y:?}"); //~ literal_string_with_formatting_arg
     x.expect(r##" {y:?} {y:?} "##); //~ literal_string_with_formatting_arg
-    "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == 'a'); //~ literal_string_with_formatting_arg
     // Ensure that it doesn't try to go in the middle of a unicode character.
-    x.expect("———{}"); //~ literal_string_with_formatting_arg
+    x.expect("———{:?}"); //~ literal_string_with_formatting_arg
 
     // Should not lint!
     format!("{y:?}");
     println!("{y:?}");
+    x.expect(" {} "); // For now we ignore `{}` to limit false positives.
+    x.expect(" {   } "); // For now we ignore `{}` to limit false positives.
     x.expect("{{y} {x");
     x.expect("{{y:?}");
     x.expect("{y:...}");
diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr
index c05d4af017c..da7eb71ac87 100644
--- a/tests/ui/literal_string_with_formatting_arg.stderr
+++ b/tests/ui/literal_string_with_formatting_arg.stderr
@@ -1,65 +1,65 @@
-error: these look like formatting arguments but are not part of a formatting macro
+error: this looks like a formatting argument but it is not part of a formatting macro
   --> tests/ui/literal_string_with_formatting_arg.rs:7:15
    |
 LL |     x.expect("{y} {}");
-   |               ^^^^^^
+   |               ^^^
    |
    = note: `-D clippy::literal-string-with-formatting-arg` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_arg)]`
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:8:15
+  --> tests/ui/literal_string_with_formatting_arg.rs:8:16
+   |
+LL |     x.expect(" {y} bla");
+   |                ^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:9:15
    |
 LL |     x.expect("{:?}");
    |               ^^^^
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:9:15
+  --> tests/ui/literal_string_with_formatting_arg.rs:10:15
    |
 LL |     x.expect("{y:?}");
    |               ^^^^^
 
 error: these look like formatting arguments but are not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:10:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:11:16
    |
 LL |     x.expect(" {y:?} {y:?} ");
    |                ^^^^^ ^^^^^
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:11:23
+  --> tests/ui/literal_string_with_formatting_arg.rs:12:23
    |
 LL |     x.expect(" {y:..} {y:?} ");
    |                       ^^^^^
 
 error: these look like formatting arguments but are not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:12:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:13:16
    |
 LL |     x.expect(r"{y:?}  {y:?} ");
    |                ^^^^^  ^^^^^
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:13:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:14:16
    |
 LL |     x.expect(r"{y:?} y:?}");
    |                ^^^^^
 
 error: these look like formatting arguments but are not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:14:19
+  --> tests/ui/literal_string_with_formatting_arg.rs:15:19
    |
 LL |     x.expect(r##" {y:?} {y:?} "##);
    |                   ^^^^^ ^^^^^
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:15:17
-   |
-LL |     "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == 'a');
-   |                 ^^
-
-error: this looks like a formatting argument but it is not part of a formatting macro
   --> tests/ui/literal_string_with_formatting_arg.rs:17:18
    |
-LL |     x.expect("———{}");
-   |                  ^^
+LL |     x.expect("———{:?}");
+   |                  ^^^^
 
 error: aborting due to 10 previous errors