about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-01-18 17:13:53 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2025-01-18 17:14:01 +0100
commit277bf089b36db59dbc2c2efa279fbe52a3fe1c4b (patch)
tree4785a8655232aba17ff53087ea2c38a861afa4aa
parente35330cabeaf312cefb4370560fd473d47eabe2d (diff)
downloadrust-277bf089b36db59dbc2c2efa279fbe52a3fe1c4b.tar.gz
rust-277bf089b36db59dbc2c2efa279fbe52a3fe1c4b.zip
Fix regression #14007
-rw-r--r--clippy_lints/src/literal_string_with_formatting_args.rs6
-rw-r--r--tests/ui/literal_string_with_formatting_arg.rs7
-rw-r--r--tests/ui/literal_string_with_formatting_arg.stderr36
3 files changed, 33 insertions, 16 deletions
diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs
index 21066a00eaf..7e3cc444a81 100644
--- a/clippy_lints/src/literal_string_with_formatting_args.rs
+++ b/clippy_lints/src/literal_string_with_formatting_args.rs
@@ -128,7 +128,11 @@ impl<'tcx> LateLintPass<'tcx> for LiteralStringWithFormattingArg {
                     pos.start += diff_len;
                     pos.end += diff_len;
 
-                    let start = fmt_str[..pos.start].rfind('{').unwrap_or(pos.start);
+                    let mut start = pos.start;
+                    while start < fmt_str.len() && !fmt_str.is_char_boundary(start) {
+                        start += 1;
+                    }
+                    let start = fmt_str[..start].rfind('{').unwrap_or(start);
                     // If this is a unicode character escape, we don't want to lint.
                     if start > 1 && fmt_str[..start].ends_with("\\u") {
                         continue;
diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs
index c9731e592e5..b9a6654d427 100644
--- a/tests/ui/literal_string_with_formatting_arg.rs
+++ b/tests/ui/literal_string_with_formatting_arg.rs
@@ -19,6 +19,13 @@ fn compiler_macro() {
     assert!(format!("{value}").is_ascii());
 }
 
+// Regression test for <https://github.com/rust-lang/rust-clippy/issues/14007>.
+fn regression_14007() {
+    let s = "{и}";
+    let ш = 12;
+    let s = "{ш}"; //~ literal_string_with_formatting_args
+}
+
 fn main() {
     let x: Option<usize> = None;
     let y = "hello";
diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr
index 1898f4f57b8..021983056bf 100644
--- a/tests/ui/literal_string_with_formatting_arg.stderr
+++ b/tests/ui/literal_string_with_formatting_arg.stderr
@@ -1,77 +1,83 @@
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:25:15
+  --> tests/ui/literal_string_with_formatting_arg.rs:26:14
    |
-LL |     x.expect("{y} {}");
-   |               ^^^
+LL |     let s = "{ш}";
+   |              ^^^
    |
    = note: `-D clippy::literal-string-with-formatting-args` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_args)]`
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:26:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:32:15
+   |
+LL |     x.expect("{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:33: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:27:15
+  --> tests/ui/literal_string_with_formatting_arg.rs:34: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:28:15
+  --> tests/ui/literal_string_with_formatting_arg.rs:35: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:29:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:36: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:30:23
+  --> tests/ui/literal_string_with_formatting_arg.rs:37: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:31:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:38: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:32:16
+  --> tests/ui/literal_string_with_formatting_arg.rs:39: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:33:19
+  --> tests/ui/literal_string_with_formatting_arg.rs:40: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:34:14
+  --> tests/ui/literal_string_with_formatting_arg.rs:41:14
    |
 LL |     assert!("{y}".is_ascii());
    |              ^^^
 
 error: this looks like a formatting argument but it is not part of a formatting macro
-  --> tests/ui/literal_string_with_formatting_arg.rs:36:18
+  --> tests/ui/literal_string_with_formatting_arg.rs:43:18
    |
 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:46:19
+  --> tests/ui/literal_string_with_formatting_arg.rs:53:19
    |
 LL |     x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint
    |                   ^^^^^
 
-error: aborting due to 12 previous errors
+error: aborting due to 13 previous errors