From 7ee4aa700321d0dc2a763a324fd1c0828d73f70f Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 27 Jun 2022 16:33:57 +0100 Subject: [PATCH] lint: port non-fmt-panic diagnostics Signed-off-by: David Wood --- .../locales/en-US/lint.ftl | 36 +++++++ compiler/rustc_errors/src/diagnostic.rs | 10 ++ compiler/rustc_lint/src/non_fmt_panic.rs | 73 ++++++------- .../const_panic_stability.e2018.stderr | 4 +- src/test/ui/non-fmt-panic.stderr | 100 +++++++++--------- 5 files changed, 132 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 34445c3940a..39c0e7d3fa6 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -72,3 +72,39 @@ lint-mixed-script-confusables = the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables .includes-note = the usage includes {$includes} .note = please recheck to make sure their usages are indeed what you want + +lint-non-fmt-panic = panic message is not a string literal + .note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021 + .more-info-note = for more information, see + .supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here + .supports-fmt-suggestion = remove the `format!(..)` macro call + .display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message + .debug-suggestion = + add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}` + .panic-suggestion = {$already_suggested -> + [true] or use + *[false] use + } std::panic::panic_any instead + +lint-non-fmt-panic-unused = + panic message contains {$count -> + [one] an unused + *[other] unused + } formatting {$count -> + [one] placeholder + *[other] placeholders + } + .note = this message is not used as a format string when given without arguments, but will be in Rust 2021 + .add-args-suggestion = add the missing {$count -> + [one] argument + *[other] arguments + } + .add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally + +lint-non-fmt-panic-braces = + panic message contains {$count -> + [one] a brace + *[other] braces + } + .note = this message is not used as a format string, but will be in Rust 2021 + .suggestion = add a "{"{"}{"}"}" format string to use the message literally diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b8545139cec..63c0d58bc9c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -39,6 +39,16 @@ pub trait IntoDiagnosticArg { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>; } +impl IntoDiagnosticArg for bool { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + if self { + DiagnosticArgValue::Str(Cow::Borrowed("true")) + } else { + DiagnosticArgValue::Str(Cow::Borrowed("false")) + } + } +} + impl IntoDiagnosticArg for String { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Owned(self)) diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 4e7aeca9ce1..cdad2d2e8f9 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -1,6 +1,6 @@ use crate::{LateContext, LateLintPass, LintContext}; use rustc_ast as ast; -use rustc_errors::{pluralize, Applicability}; +use rustc_errors::{fluent, Applicability}; use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::lint::in_external_macro; @@ -120,9 +120,10 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| { - let mut l = lint.build("panic message is not a string literal"); - l.note(&format!("this usage of {}!() is deprecated; it will be a hard error in Rust 2021", symbol)); - l.note("for more information, see "); + let mut l = lint.build(fluent::lint::non_fmt_panic); + l.set_arg("name", symbol); + l.note(fluent::lint::note); + l.note(fluent::lint::more_info_note); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. l.emit(); @@ -130,10 +131,10 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. - l.note(format!("the {}!() macro supports formatting, so there's no need for the format!() macro here", symbol).as_str()); + l.note(fluent::lint::supports_fmt_note); if let Some((open, close, _)) = find_delimiters(cx, arg_span) { l.multipart_suggestion( - "remove the `format!(..)` macro call", + fluent::lint::supports_fmt_suggestion, vec![ (arg_span.until(open.shrink_to_hi()), "".into()), (close.until(arg_span.shrink_to_hi()), "".into()), @@ -153,12 +154,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc ); let (suggest_display, suggest_debug) = cx.tcx.infer_ctxt().enter(|infcx| { - let display = is_str || cx.tcx.get_diagnostic_item(sym::Display).map(|t| { - infcx.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env).may_apply() - }) == Some(true); - let debug = !display && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { - infcx.type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env).may_apply() - }) == Some(true); + let display = is_str + || cx.tcx.get_diagnostic_item(sym::Display).map(|t| { + infcx + .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) + .may_apply() + }) == Some(true); + let debug = !display + && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { + infcx + .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) + .may_apply() + }) == Some(true); (display, debug) }); @@ -175,17 +182,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if suggest_display { l.span_suggestion_verbose( arg_span.shrink_to_lo(), - "add a \"{}\" format string to Display the message", + fluent::lint::display_suggestion, "\"{}\", ", fmt_applicability, ); } else if suggest_debug { + l.set_arg("ty", ty); l.span_suggestion_verbose( arg_span.shrink_to_lo(), - &format!( - "add a \"{{:?}}\" format string to use the Debug implementation of `{}`", - ty, - ), + fluent::lint::debug_suggestion, "\"{:?}\", ", fmt_applicability, ); @@ -193,15 +198,9 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if suggest_panic_any { if let Some((open, close, del)) = find_delimiters(cx, span) { + l.set_arg("already_suggested", suggest_display || suggest_debug); l.multipart_suggestion( - &format!( - "{}use std::panic::panic_any instead", - if suggest_display || suggest_debug { - "or " - } else { - "" - }, - ), + fluent::lint::panic_suggestion, if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] } else { @@ -260,21 +259,19 @@ fn check_panic_str<'tcx>( .collect(), }; 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", - }); - l.note("this message is not used as a format string when given without arguments, but will be in Rust 2021"); + let mut l = lint.build(fluent::lint::non_fmt_panic_unused); + l.set_arg("count", n_arguments); + l.note(fluent::lint::note); if is_arg_inside_call(arg.span, span) { l.span_suggestion( arg.span.shrink_to_hi(), - &format!("add the missing argument{}", pluralize!(n_arguments)), + fluent::lint::add_args_suggestion, ", ...", Applicability::HasPlaceholders, ); l.span_suggestion( arg.span.shrink_to_lo(), - "or add a \"{}\" format string to use the message literally", + fluent::lint::add_fmt_suggestion, "\"{}\", ", Applicability::MachineApplicable, ); @@ -289,17 +286,15 @@ fn check_panic_str<'tcx>( .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", - }; + let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2); 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"); + let mut l = lint.build(fluent::lint::non_fmt_panic_braces); + l.set_arg("count", count); + l.note(fluent::lint::note); if is_arg_inside_call(arg.span, span) { l.span_suggestion( arg.span.shrink_to_lo(), - "add a \"{}\" format string to use the message literally", + fluent::lint::suggestion, "\"{}\", ", Applicability::MachineApplicable, ); diff --git a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr index 94cf64fff19..f06dedc2298 100644 --- a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr +++ b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -5,9 +5,9 @@ LL | panic!({ "foo" }); | ^^^^^^^^^ | = note: `#[warn(non_fmt_panics)]` on by default - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", { "foo" }); | +++++ diff --git a/src/test/ui/non-fmt-panic.stderr b/src/test/ui/non-fmt-panic.stderr index 4da97ed5d60..6e4434e6f33 100644 --- a/src/test/ui/non-fmt-panic.stderr +++ b/src/test/ui/non-fmt-panic.stderr @@ -73,9 +73,9 @@ warning: panic message is not a string literal LL | assert!(false, S); | ^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | assert!(false, "{}", S); | +++++ @@ -86,9 +86,9 @@ warning: panic message is not a string literal LL | assert!(false, 123); | ^^^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | assert!(false, "{}", 123); | +++++ @@ -99,9 +99,9 @@ warning: panic message is not a string literal LL | assert!(false, Some(123)); | ^^^^^^^^^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{:?}" format string to use the Debug implementation of `Option` +help: add a "{:?}" format string to use the `Debug` implementation of `Option` | LL | assert!(false, "{:?}", Some(123)); | +++++++ @@ -124,9 +124,9 @@ warning: panic message is not a string literal LL | panic!(C); | ^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", C); | +++++ @@ -137,9 +137,9 @@ warning: panic message is not a string literal LL | panic!(S); | ^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", S); | +++++ @@ -150,9 +150,9 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | - = note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | unreachable!("{}", S); | +++++ @@ -163,9 +163,9 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | - = note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | unreachable!("{}", S); | +++++ @@ -176,9 +176,9 @@ warning: panic message is not a string literal LL | std::panic!(123); | ^^^ | - = note: this usage of std::panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | std::panic!("{}", 123); | +++++ @@ -193,9 +193,9 @@ warning: panic message is not a string literal LL | core::panic!(&*"abc"); | ^^^^^^^ | - = note: this usage of core::panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | core::panic!("{}", &*"abc"); | +++++ @@ -206,9 +206,9 @@ warning: panic message is not a string literal LL | panic!(Some(123)); | ^^^^^^^^^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{:?}" format string to use the Debug implementation of `Option` +help: add a "{:?}" format string to use the `Debug` implementation of `Option` | LL | panic!("{:?}", Some(123)); | +++++++ @@ -259,9 +259,9 @@ warning: panic message is not a string literal LL | panic!(a!()); | ^^^^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", a!()); | +++++ @@ -276,9 +276,9 @@ warning: panic message is not a string literal LL | unreachable!(a!()); | ^^^^ | - = note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | unreachable!("{}", a!()); | +++++ @@ -289,9 +289,9 @@ warning: panic message is not a string literal LL | panic!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see - = note: the panic!() macro supports formatting, so there's no need for the format!() macro here + = note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here help: remove the `format!(..)` macro call | LL - panic!(format!("{}", 1)); @@ -304,9 +304,9 @@ warning: panic message is not a string literal LL | unreachable!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | - = note: this usage of unreachable!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see - = note: the unreachable!() macro supports formatting, so there's no need for the format!() macro here + = note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here help: remove the `format!(..)` macro call | LL - unreachable!(format!("{}", 1)); @@ -319,9 +319,9 @@ warning: panic message is not a string literal LL | assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see - = note: the assert!() macro supports formatting, so there's no need for the format!() macro here + = note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here help: remove the `format!(..)` macro call | LL - assert!(false, format!("{}", 1)); @@ -334,9 +334,9 @@ warning: panic message is not a string literal LL | debug_assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | - = note: this usage of debug_assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see - = note: the debug_assert!() macro supports formatting, so there's no need for the format!() macro here + = note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here help: remove the `format!(..)` macro call | LL - debug_assert!(false, format!("{}", 1)); @@ -349,9 +349,9 @@ warning: panic message is not a string literal LL | panic![123]; | ^^^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!["{}", 123]; | +++++ @@ -366,9 +366,9 @@ warning: panic message is not a string literal LL | panic!{123}; | ^^^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!{"{}", 123}; | +++++ @@ -385,7 +385,7 @@ LL | panic!(v); | | | help: use std::panic::panic_any instead: `std::panic::panic_any` | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see warning: panic message is not a string literal @@ -394,7 +394,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see warning: panic message is not a string literal @@ -403,9 +403,9 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{:?}" format string to use the Debug implementation of `T` +help: add a "{:?}" format string to use the `Debug` implementation of `T` | LL | panic!("{:?}", v); | +++++++ @@ -420,9 +420,9 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{:?}" format string to use the Debug implementation of `T` +help: add a "{:?}" format string to use the `Debug` implementation of `T` | LL | assert!(false, "{:?}", v); | +++++++ @@ -433,9 +433,9 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", v); | +++++ @@ -450,9 +450,9 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | assert!(false, "{}", v); | +++++ @@ -463,9 +463,9 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | - = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | panic!("{}", v); | +++++ @@ -480,9 +480,9 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | - = note: this usage of assert!() is deprecated; it will be a hard error in Rust 2021 + = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see -help: add a "{}" format string to Display the message +help: add a "{}" format string to `Display` the message | LL | assert!(false, "{}", v); | +++++