about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2023-02-25 23:39:15 +0100
committerSamuel Tardieu <sam@rfc1149.net>2023-02-25 23:48:17 +0100
commit64775f30c22e8e828a8dec13057e927d363701ac (patch)
tree79eab30c79ea02abe58596ad18d43b309b0149cc
parentb528cc90bc35a111125bfd2382bfcdcd345cea69 (diff)
downloadrust-64775f30c22e8e828a8dec13057e927d363701ac.tar.gz
rust-64775f30c22e8e828a8dec13057e927d363701ac.zip
Do not panic when analyzing the malformed origin of a format string
-rw-r--r--clippy_utils/src/macros.rs9
-rw-r--r--tests/ui/format.fixed6
-rw-r--r--tests/ui/format.rs6
-rw-r--r--tests/ui/format.stderr30
4 files changed, 35 insertions, 16 deletions
diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs
index 63dccbf697c..be6133d3202 100644
--- a/clippy_utils/src/macros.rs
+++ b/clippy_utils/src/macros.rs
@@ -391,11 +391,18 @@ impl FormatString {
         };
 
         let mut unescaped = String::with_capacity(inner.len());
+        // Sometimes the original string comes from a macro which accepts a malformed string, such as in a
+        // #[display(""somestring)] attribute (accepted by the `displaythis` crate). Reconstructing the
+        // string from the span will not be possible, so we will just return None here.
+        let mut unparsable = false;
         unescape_literal(inner, mode, &mut |_, ch| match ch {
             Ok(ch) => unescaped.push(ch),
             Err(e) if !e.is_fatal() => (),
-            Err(e) => panic!("{e:?}"),
+            Err(_) => unparsable = true,
         });
+        if unparsable {
+            return None;
+        }
 
         let mut parts = Vec::new();
         let _: Option<!> = for_each_expr(pieces, |expr| {
diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed
index beedf2c1db2..cd2f70ee8b0 100644
--- a/tests/ui/format.fixed
+++ b/tests/ui/format.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+// aux-build: proc_macro_with_span.rs
 #![warn(clippy::useless_format)]
 #![allow(
     unused_tuple_struct_fields,
@@ -9,6 +10,8 @@
     clippy::uninlined_format_args
 )]
 
+extern crate proc_macro_with_span;
+
 struct Foo(pub String);
 
 macro_rules! foo {
@@ -87,4 +90,7 @@ fn main() {
     let _ = abc.to_string();
     let xx = "xx";
     let _ = xx.to_string();
+
+    // Issue #10148
+    println!(proc_macro_with_span::with_span!(""something ""));
 }
diff --git a/tests/ui/format.rs b/tests/ui/format.rs
index e805f181889..c22345a79d4 100644
--- a/tests/ui/format.rs
+++ b/tests/ui/format.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+// aux-build: proc_macro_with_span.rs
 #![warn(clippy::useless_format)]
 #![allow(
     unused_tuple_struct_fields,
@@ -9,6 +10,8 @@
     clippy::uninlined_format_args
 )]
 
+extern crate proc_macro_with_span;
+
 struct Foo(pub String);
 
 macro_rules! foo {
@@ -89,4 +92,7 @@ fn main() {
     let _ = format!("{abc}");
     let xx = "xx";
     let _ = format!("{xx}");
+
+    // Issue #10148
+    println!(proc_macro_with_span::with_span!(""something ""));
 }
diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr
index 0ef0ac655d3..a0e5d5c8ad2 100644
--- a/tests/ui/format.stderr
+++ b/tests/ui/format.stderr
@@ -1,5 +1,5 @@
 error: useless use of `format!`
-  --> $DIR/format.rs:19:5
+  --> $DIR/format.rs:22:5
    |
 LL |     format!("foo");
    |     ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
@@ -7,19 +7,19 @@ LL |     format!("foo");
    = note: `-D clippy::useless-format` implied by `-D warnings`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:20:5
+  --> $DIR/format.rs:23:5
    |
 LL |     format!("{{}}");
    |     ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:21:5
+  --> $DIR/format.rs:24:5
    |
 LL |     format!("{{}} abc {{}}");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:22:5
+  --> $DIR/format.rs:25:5
    |
 LL | /     format!(
 LL | |         r##"foo {{}}
@@ -34,67 +34,67 @@ LL ~ " bar"##.to_string();
    |
 
 error: useless use of `format!`
-  --> $DIR/format.rs:27:13
+  --> $DIR/format.rs:30:13
    |
 LL |     let _ = format!("");
    |             ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:29:5
+  --> $DIR/format.rs:32:5
    |
 LL |     format!("{}", "foo");
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:37:5
+  --> $DIR/format.rs:40:5
    |
 LL |     format!("{}", arg);
    |     ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:67:5
+  --> $DIR/format.rs:70:5
    |
 LL |     format!("{}", 42.to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:69:5
+  --> $DIR/format.rs:72:5
    |
 LL |     format!("{}", x.display().to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:73:18
+  --> $DIR/format.rs:76:18
    |
 LL |     let _ = Some(format!("{}", a + "bar"));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:77:22
+  --> $DIR/format.rs:80:22
    |
 LL |     let _s: String = format!("{}", &*v.join("/n"));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:83:13
+  --> $DIR/format.rs:86:13
    |
 LL |     let _ = format!("{x}");
    |             ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:85:13
+  --> $DIR/format.rs:88:13
    |
 LL |     let _ = format!("{y}", y = x);
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:89:13
+  --> $DIR/format.rs:92:13
    |
 LL |     let _ = format!("{abc}");
    |             ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`
 
 error: useless use of `format!`
-  --> $DIR/format.rs:91:13
+  --> $DIR/format.rs:94:13
    |
 LL |     let _ = format!("{xx}");
    |             ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`