about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2020-10-18 22:26:36 +0200
committerMara Bos <m-ou.se@m-ou.se>2020-10-18 22:26:36 +0200
commitda66a501f6423d498627453dd7d0f8bc874ee42d (patch)
treeb63cfe8b4498fdac6c9e197baee1a4ca4d40ad19
parent462ee9c1b5eb0ae759e2fcc6f35dc5db4fc04367 (diff)
downloadrust-da66a501f6423d498627453dd7d0f8bc874ee42d.tar.gz
rust-da66a501f6423d498627453dd7d0f8bc874ee42d.zip
Specialize panic_fmt lint for the {core,std}::panic!() macros.
It now only reacts to expansion of those macros, and suggests
inserting `"{}", ` in the right place.
-rw-r--r--compiler/rustc_lint/src/panic_fmt.rs27
-rw-r--r--compiler/rustc_span/src/symbol.rs2
2 files changed, 24 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/panic_fmt.rs b/compiler/rustc_lint/src/panic_fmt.rs
index 0d3649ec543..e0752515377 100644
--- a/compiler/rustc_lint/src/panic_fmt.rs
+++ b/compiler/rustc_lint/src/panic_fmt.rs
@@ -1,7 +1,9 @@
 use crate::{LateContext, LateLintPass, LintContext};
 use rustc_ast as ast;
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty;
+use rustc_span::sym;
 
 declare_lint! {
     /// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal.
@@ -46,11 +48,26 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
     if let hir::ExprKind::Lit(lit) = &arg.kind {
         if let ast::LitKind::Str(sym, _) = lit.node {
             if sym.as_str().contains(&['{', '}'][..]) {
-                cx.struct_span_lint(PANIC_FMT, f.span, |lint| {
-                    lint.build("Panic message contains a brace")
-                    .note("This message is not used as a format string, but will be in a future Rust version")
-                    .emit();
-                });
+                let expn = f.span.ctxt().outer_expn_data();
+                if let Some(id) = expn.macro_def_id {
+                    if cx.tcx.is_diagnostic_item(sym::std_panic_macro, id)
+                        || cx.tcx.is_diagnostic_item(sym::core_panic_macro, id)
+                    {
+                        cx.struct_span_lint(PANIC_FMT, expn.call_site, |lint| {
+                            let mut l = lint.build("Panic message contains a brace");
+                            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) {
+                                l.span_suggestion(
+                                    arg.span.shrink_to_lo(),
+                                    "add a \"{}\" format string to use the message literally",
+                                    "\"{}\", ".into(),
+                                    Applicability::MachineApplicable,
+                                );
+                            }
+                            l.emit();
+                        });
+                    }
+                }
             }
         }
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 3a2a3adce35..c36d6380771 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -393,6 +393,7 @@ symbols! {
         copysignf64,
         core,
         core_intrinsics,
+        core_panic_macro,
         cosf32,
         cosf64,
         crate_id,
@@ -1064,6 +1065,7 @@ symbols! {
         staticlib,
         std,
         std_inject,
+        std_panic_macro,
         stmt,
         stmt_expr_attributes,
         stop_after_dataflow,