Improve panic_fmt error messages for invalid format strings too.
This commit is contained in:
parent
6b44662669
commit
190c3ad64e
3 changed files with 66 additions and 16 deletions
|
@ -4,7 +4,7 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_parse_format::{ParseMode, Parser, Piece};
|
use rustc_parse_format::{ParseMode, Parser, Piece};
|
||||||
use rustc_span::sym;
|
use rustc_span::{sym, InnerSpan};
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal.
|
/// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal.
|
||||||
|
@ -71,7 +71,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut fmt_parser =
|
let mut fmt_parser =
|
||||||
Parser::new(fmt.as_ref(), style, snippet, false, ParseMode::Format);
|
Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
|
||||||
let n_arguments =
|
let n_arguments =
|
||||||
(&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
|
(&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
|
||||||
|
|
||||||
|
@ -115,8 +115,22 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
||||||
l.emit();
|
l.emit();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cx.struct_span_lint(PANIC_FMT, expn.call_site, |lint| {
|
let brace_spans: Option<Vec<_>> = snippet
|
||||||
let mut l = lint.build("panic message contains a brace");
|
.filter(|s| s.starts_with('"') || s.starts_with("r#"))
|
||||||
|
.map(|s| {
|
||||||
|
s.char_indices()
|
||||||
|
.filter(|&(_, c)| c == '{' || c == '}')
|
||||||
|
.map(|(i, _)| {
|
||||||
|
fmt_span.from_inner(InnerSpan { start: i, end: i + 1 })
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
let msg = match &brace_spans {
|
||||||
|
Some(v) if v.len() == 1 => "panic message contains a brace",
|
||||||
|
_ => "panic message contains braces",
|
||||||
|
};
|
||||||
|
cx.struct_span_lint(PANIC_FMT, brace_spans.unwrap_or(vec![expn.call_site]), |lint| {
|
||||||
|
let mut l = lint.build(msg);
|
||||||
l.note("this message is not used as a format string, but will be in a future Rust version");
|
l.note("this message is not used as a format string, but will be in a future Rust version");
|
||||||
if expn.call_site.contains(arg.span) {
|
if expn.call_site.contains(arg.span) {
|
||||||
l.span_suggestion(
|
l.span_suggestion(
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
// build-pass (FIXME(62277): should be check-pass)
|
// build-pass (FIXME(62277): should be check-pass)
|
||||||
|
|
||||||
|
const C: &str = "abc {}";
|
||||||
|
static S: &str = "{bla}";
|
||||||
|
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
fn main() {
|
fn main() {
|
||||||
panic!("here's a brace: {"); //~ WARN panic message contains a brace
|
panic!("here's a brace: {"); //~ WARN panic message contains a brace
|
||||||
std::panic!("another one: }"); //~ WARN panic message contains a brace
|
std::panic!("another one: }"); //~ WARN panic message contains a brace
|
||||||
core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder
|
core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder
|
||||||
assert!(false, "{:03x} {test} bla"); //~ WARN panic message contains unused formatting placeholders
|
assert!(false, "{:03x} {test} bla");
|
||||||
debug_assert!(false, "{{}} bla"); //~ WARN panic message contains a brace
|
//~^ WARN panic message contains unused formatting placeholders
|
||||||
|
debug_assert!(false, "{{}} bla"); //~ WARN panic message contains braces
|
||||||
|
panic!(C); // No warning (yet)
|
||||||
|
panic!(S); // No warning (yet)
|
||||||
|
panic!(concat!("{", "}")); //~ WARN panic message contains an unused formatting placeholder
|
||||||
|
panic!(concat!("{", "{")); //~ WARN panic message contains braces
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
warning: panic message contains a brace
|
warning: panic message contains a brace
|
||||||
--> $DIR/panic-brace.rs:5:5
|
--> $DIR/panic-brace.rs:8:29
|
||||||
|
|
|
|
||||||
LL | panic!("here's a brace: {");
|
LL | panic!("here's a brace: {");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
= note: `#[warn(panic_fmt)]` on by default
|
= note: `#[warn(panic_fmt)]` on by default
|
||||||
= note: this message is not used as a format string, but will be in a future Rust version
|
= note: this message is not used as a format string, but will be in a future Rust version
|
||||||
|
@ -12,10 +12,10 @@ LL | panic!("{}", "here's a brace: {");
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: panic message contains a brace
|
warning: panic message contains a brace
|
||||||
--> $DIR/panic-brace.rs:6:5
|
--> $DIR/panic-brace.rs:9:31
|
||||||
|
|
|
|
||||||
LL | std::panic!("another one: }");
|
LL | std::panic!("another one: }");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
= note: this message is not used as a format string, but will be in a future Rust version
|
= note: this message is not used as a format string, but will be in a future Rust version
|
||||||
help: add a "{}" format string to use the message literally
|
help: add a "{}" format string to use the message literally
|
||||||
|
@ -24,7 +24,7 @@ LL | std::panic!("{}", "another one: }");
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: panic message contains an unused formatting placeholder
|
warning: panic message contains an unused formatting placeholder
|
||||||
--> $DIR/panic-brace.rs:7:25
|
--> $DIR/panic-brace.rs:10:25
|
||||||
|
|
|
|
||||||
LL | core::panic!("Hello {}");
|
LL | core::panic!("Hello {}");
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -40,7 +40,7 @@ LL | core::panic!("{}", "Hello {}");
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: panic message contains unused formatting placeholders
|
warning: panic message contains unused formatting placeholders
|
||||||
--> $DIR/panic-brace.rs:8:21
|
--> $DIR/panic-brace.rs:11:21
|
||||||
|
|
|
|
||||||
LL | assert!(false, "{:03x} {test} bla");
|
LL | assert!(false, "{:03x} {test} bla");
|
||||||
| ^^^^^^ ^^^^^^
|
| ^^^^^^ ^^^^^^
|
||||||
|
@ -55,11 +55,11 @@ help: or add a "{}" format string to use the message literally
|
||||||
LL | assert!(false, "{}", "{:03x} {test} bla");
|
LL | assert!(false, "{}", "{:03x} {test} bla");
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: panic message contains a brace
|
warning: panic message contains braces
|
||||||
--> $DIR/panic-brace.rs:9:5
|
--> $DIR/panic-brace.rs:13:27
|
||||||
|
|
|
|
||||||
LL | debug_assert!(false, "{{}} bla");
|
LL | debug_assert!(false, "{{}} bla");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= note: this message is not used as a format string, but will be in a future Rust version
|
= note: this message is not used as a format string, but will be in a future Rust version
|
||||||
help: add a "{}" format string to use the message literally
|
help: add a "{}" format string to use the message literally
|
||||||
|
@ -67,5 +67,33 @@ help: add a "{}" format string to use the message literally
|
||||||
LL | debug_assert!(false, "{}", "{{}} bla");
|
LL | debug_assert!(false, "{}", "{{}} bla");
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: 5 warnings emitted
|
warning: panic message contains an unused formatting placeholder
|
||||||
|
--> $DIR/panic-brace.rs:16:12
|
||||||
|
|
|
||||||
|
LL | panic!(concat!("{", "}"));
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this message is not used as a format string when given without arguments, but will be in a future Rust version
|
||||||
|
help: add the missing argument(s)
|
||||||
|
|
|
||||||
|
LL | panic!(concat!("{", "}"), ...);
|
||||||
|
| ^^^^^
|
||||||
|
help: or add a "{}" format string to use the message literally
|
||||||
|
|
|
||||||
|
LL | panic!("{}", concat!("{", "}"));
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
warning: panic message contains braces
|
||||||
|
--> $DIR/panic-brace.rs:17:5
|
||||||
|
|
|
||||||
|
LL | panic!(concat!("{", "{"));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this message is not used as a format string, but will be in a future Rust version
|
||||||
|
help: add a "{}" format string to use the message literally
|
||||||
|
|
|
||||||
|
LL | panic!("{}", concat!("{", "{"));
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
warning: 7 warnings emitted
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue