]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_lint/src/non_fmt_panic.rs
Auto merge of #86492 - hyd-dev:no-mangle-method, r=petrochenkov
[rust.git] / compiler / rustc_lint / src / non_fmt_panic.rs
index 3ea5a3bcc3b98a3b721472e2aa4040b9c8b9d68c..ec53625f10525014264c53f0dc895ec7c858aa19 100644 (file)
@@ -2,6 +2,7 @@
 use rustc_ast as ast;
 use rustc_errors::{pluralize, Applicability};
 use rustc_hir as hir;
+use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_parse_format::{ParseMode, Parser, Piece};
 use rustc_session::lint::FutureIncompatibilityReason;
@@ -9,7 +10,7 @@
 use rustc_span::{hygiene, sym, symbol::kw, symbol::SymbolStr, InnerSpan, Span, Symbol};
 
 declare_lint! {
-    /// The `non_fmt_panic` lint detects `panic!(..)` invocations where the first
+    /// The `non_fmt_panics` lint detects `panic!(..)` invocations where the first
     /// argument is not a formatting string.
     ///
     /// ### Example
@@ -29,7 +30,7 @@
     /// an `i32` as message.
     ///
     /// Rust 2021 always interprets the first argument as format string.
-    NON_FMT_PANIC,
+    NON_FMT_PANICS,
     Warn,
     "detect single-argument panic!() invocations in which the argument is not a format string",
     @future_incompatible = FutureIncompatibleInfo {
@@ -39,7 +40,7 @@
     report_in_external_macro
 }
 
-declare_lint_pass!(NonPanicFmt => [NON_FMT_PANIC]);
+declare_lint_pass!(NonPanicFmt => [NON_FMT_PANICS]);
 
 impl<'tcx> LateLintPass<'tcx> for NonPanicFmt {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
@@ -75,6 +76,11 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
 
     let (span, panic, symbol_str) = panic_call(cx, f);
 
+    if in_external_macro(cx.sess(), span) {
+        // Nothing that can be done about it in the current crate.
+        return;
+    }
+
     // Find the span of the argument to `panic!()`, before expansion in the
     // case of `panic!(some_macro!())`.
     // We don't use source_callsite(), because this `panic!(..)` might itself
@@ -91,7 +97,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
         arg_span = expn.call_site;
     }
 
-    cx.struct_span_lint(NON_FMT_PANIC, arg_span, |lint| {
+    cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| {
         let mut l = lint.build("panic message is not a string literal");
         l.note("this usage of panic!() is deprecated; it will be a hard error in Rust 2021");
         l.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>");
@@ -152,6 +158,13 @@ fn check_panic_str<'tcx>(
         return;
     }
 
+    let (span, _, _) = panic_call(cx, f);
+
+    if in_external_macro(cx.sess(), span) && in_external_macro(cx.sess(), arg.span) {
+        // Nothing that can be done about it in the current crate.
+        return;
+    }
+
     let fmt_span = arg.span.source_callsite();
 
     let (snippet, style) = match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) {
@@ -167,14 +180,12 @@ fn check_panic_str<'tcx>(
         Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
     let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
 
-    let (span, _, _) = panic_call(cx, f);
-
     if n_arguments > 0 && fmt_parser.errors.is_empty() {
         let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] {
             [] => vec![fmt_span],
             v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(),
         };
-        cx.struct_span_lint(NON_FMT_PANIC, arg_spans, |lint| {
+        cx.struct_span_lint(NON_FMT_PANICS, arg_spans, |lint| {
             let mut l = lint.build(match n_arguments {
                 1 => "panic message contains an unused formatting placeholder",
                 _ => "panic message contains unused formatting placeholders",
@@ -208,7 +219,7 @@ fn check_panic_str<'tcx>(
             Some(v) if v.len() == 1 => "panic message contains a brace",
             _ => "panic message contains braces",
         };
-        cx.struct_span_lint(NON_FMT_PANIC, brace_spans.unwrap_or_else(|| vec![span]), |lint| {
+        cx.struct_span_lint(NON_FMT_PANICS, brace_spans.unwrap_or_else(|| vec![span]), |lint| {
             let mut l = lint.build(msg);
             l.note("this message is not used as a format string, but will be in Rust 2021");
             if span.contains(arg.span) {
@@ -256,10 +267,6 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
     }
 
     let macro_symbol =
-        if let hygiene::ExpnKind::Macro { kind: _, name: symbol, proc_macro: _ } = expn.kind {
-            symbol
-        } else {
-            Symbol::intern("panic")
-        };
+        if let hygiene::ExpnKind::Macro(_, symbol) = expn.kind { symbol } else { sym::panic };
     (expn.call_site, panic_macro, macro_symbol.as_str())
 }