Auto merge of #10401 - samueltardieu:issue-10148, r=Alexendoo

Do not panic when analyzing the malformed origin of a format string

Fixes #10148. This will trigger only when generating format strings while accepting weird things in a procedural macro and setting the span to something which is not a string.

changelog: none
This commit is contained in:
bors 2023-02-25 23:05:23 +00:00
commit 51551193d8
4 changed files with 35 additions and 16 deletions

View File

@ -391,11 +391,18 @@ fn new(cx: &LateContext<'_>, pieces: &Expr<'_>) -> Option<Self> {
}; };
let mut unescaped = String::with_capacity(inner.len()); 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 { unescape_literal(inner, mode, &mut |_, ch| match ch {
Ok(ch) => unescaped.push(ch), Ok(ch) => unescaped.push(ch),
Err(e) if !e.is_fatal() => (), Err(e) if !e.is_fatal() => (),
Err(e) => panic!("{e:?}"), Err(_) => unparsable = true,
}); });
if unparsable {
return None;
}
let mut parts = Vec::new(); let mut parts = Vec::new();
let _: Option<!> = for_each_expr(pieces, |expr| { let _: Option<!> = for_each_expr(pieces, |expr| {

View File

@ -1,4 +1,5 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs
#![warn(clippy::useless_format)] #![warn(clippy::useless_format)]
#![allow( #![allow(
unused_tuple_struct_fields, unused_tuple_struct_fields,
@ -9,6 +10,8 @@
clippy::uninlined_format_args clippy::uninlined_format_args
)] )]
extern crate proc_macro_with_span;
struct Foo(pub String); struct Foo(pub String);
macro_rules! foo { macro_rules! foo {
@ -87,4 +90,7 @@ fn main() {
let _ = abc.to_string(); let _ = abc.to_string();
let xx = "xx"; let xx = "xx";
let _ = xx.to_string(); let _ = xx.to_string();
// Issue #10148
println!(proc_macro_with_span::with_span!(""something ""));
} }

View File

@ -1,4 +1,5 @@
// run-rustfix // run-rustfix
// aux-build: proc_macro_with_span.rs
#![warn(clippy::useless_format)] #![warn(clippy::useless_format)]
#![allow( #![allow(
unused_tuple_struct_fields, unused_tuple_struct_fields,
@ -9,6 +10,8 @@
clippy::uninlined_format_args clippy::uninlined_format_args
)] )]
extern crate proc_macro_with_span;
struct Foo(pub String); struct Foo(pub String);
macro_rules! foo { macro_rules! foo {
@ -89,4 +92,7 @@ fn main() {
let _ = format!("{abc}"); let _ = format!("{abc}");
let xx = "xx"; let xx = "xx";
let _ = format!("{xx}"); let _ = format!("{xx}");
// Issue #10148
println!(proc_macro_with_span::with_span!(""something ""));
} }

View File

@ -1,5 +1,5 @@
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:19:5 --> $DIR/format.rs:22:5
| |
LL | format!("foo"); LL | format!("foo");
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
@ -7,19 +7,19 @@ LL | format!("foo");
= note: `-D clippy::useless-format` implied by `-D warnings` = note: `-D clippy::useless-format` implied by `-D warnings`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:20:5 --> $DIR/format.rs:23:5
| |
LL | format!("{{}}"); LL | format!("{{}}");
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:21:5 --> $DIR/format.rs:24:5
| |
LL | format!("{{}} abc {{}}"); LL | format!("{{}} abc {{}}");
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:22:5 --> $DIR/format.rs:25:5
| |
LL | / format!( LL | / format!(
LL | | r##"foo {{}} LL | | r##"foo {{}}
@ -34,67 +34,67 @@ LL ~ " bar"##.to_string();
| |
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:27:13 --> $DIR/format.rs:30:13
| |
LL | let _ = format!(""); LL | let _ = format!("");
| ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:29:5 --> $DIR/format.rs:32:5
| |
LL | format!("{}", "foo"); LL | format!("{}", "foo");
| ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:37:5 --> $DIR/format.rs:40:5
| |
LL | format!("{}", arg); LL | format!("{}", arg);
| ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:67:5 --> $DIR/format.rs:70:5
| |
LL | format!("{}", 42.to_string()); LL | format!("{}", 42.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:69:5 --> $DIR/format.rs:72:5
| |
LL | format!("{}", x.display().to_string()); LL | format!("{}", x.display().to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:73:18 --> $DIR/format.rs:76:18
| |
LL | let _ = Some(format!("{}", a + "bar")); LL | let _ = Some(format!("{}", a + "bar"));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:77:22 --> $DIR/format.rs:80:22
| |
LL | let _s: String = format!("{}", &*v.join("/n")); LL | let _s: String = format!("{}", &*v.join("/n"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:83:13 --> $DIR/format.rs:86:13
| |
LL | let _ = format!("{x}"); LL | let _ = format!("{x}");
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:85:13 --> $DIR/format.rs:88:13
| |
LL | let _ = format!("{y}", y = x); LL | let _ = format!("{y}", y = x);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:89:13 --> $DIR/format.rs:92:13
| |
LL | let _ = format!("{abc}"); LL | let _ = format!("{abc}");
| ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`
error: useless use of `format!` error: useless use of `format!`
--> $DIR/format.rs:91:13 --> $DIR/format.rs:94:13
| |
LL | let _ = format!("{xx}"); LL | let _ = format!("{xx}");
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`