From 7d2eba6311dfaf615866442fb9e3730a8d888748 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 27 Jun 2022 11:38:45 +0100 Subject: middle: translation in `LintDiagnosticBuilder` Accept `DiagnosticMessage` in `LintDiagnosticBuilder::build` so that lints can be built with translatable diagnostic messages. Signed-off-by: David Wood --- compiler/rustc_errors/src/diagnostic_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9e0a99849a3..1ad33ef25b7 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -529,7 +529,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { applicability: Applicability, ) -> &mut Self); - forward!(pub fn set_primary_message(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn set_primary_message(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn set_span(&mut self, sp: impl Into) -> &mut Self); forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self); forward!(pub fn set_arg( -- cgit 1.4.1-3-g733a5 From 7ee4aa700321d0dc2a763a324fd1c0828d73f70f Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 27 Jun 2022 16:33:57 +0100 Subject: lint: port non-fmt-panic diagnostics Signed-off-by: David Wood --- .../rustc_error_messages/locales/en-US/lint.ftl | 36 ++++++++ compiler/rustc_errors/src/diagnostic.rs | 10 +++ compiler/rustc_lint/src/non_fmt_panic.rs | 73 +++++++-------- .../const-eval/const_panic_stability.e2018.stderr | 4 +- src/test/ui/non-fmt-panic.stderr | 100 ++++++++++----------- 5 files changed, 132 insertions(+), 91 deletions(-) (limited to 'compiler/rustc_errors/src') 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); | +++++ -- cgit 1.4.1-3-g733a5 From 7a9bef4d83a091be25fdf0f1beaade66eec0cd92 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 27 Jun 2022 17:42:47 +0100 Subject: lint: port overflowing literals diagnostics Signed-off-by: David Wood --- .../rustc_error_messages/locales/en-US/lint.ftl | 25 +++++++ compiler/rustc_errors/src/diagnostic.rs | 12 ++++ compiler/rustc_lint/src/types.rs | 83 +++++++++++----------- 3 files changed, 79 insertions(+), 41 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 621af76f695..ae53fb4821b 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -147,3 +147,28 @@ lint-drop-trait-constraints = lint-drop-glue = types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped + +lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}` + .suggestion = use an inclusive range instead + +lint-overflowing-bin-hex = literal out of range for `{$ty}` + .negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` + .negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}` + .positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}` + .suggestion = consider using the type `{$suggestion_ty}` instead + .help = consider using the type `{$suggestion_ty}` instead + +lint-overflowing-int = literal out of range for `{$ty}` + .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}` + .help = consider using the type `{$suggestion_ty}` instead + +lint-only-cast-u8-to-char = only `u8` can be cast into `char` + .suggestion = use a `char` literal instead + +lint-overflowing-uint = literal out of range for `{$ty}` + .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}` + +lint-overflowing-literal = literal out of range for `{$ty}` + .note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY` + +lint-unused-comparisons = comparison is useless due to type limits diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 63c0d58bc9c..576248ae7c2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -49,6 +49,18 @@ impl IntoDiagnosticArg for bool { } } +impl IntoDiagnosticArg for i128 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u128 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + impl IntoDiagnosticArg for String { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Owned(self)) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 5579e4d19cf..c92459c770b 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -2,7 +2,7 @@ use crate::{LateContext, LateLintPass, LintContext}; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::Applicability; +use rustc_errors::{fluent, Applicability}; use rustc_hir as hir; use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; @@ -139,7 +139,8 @@ fn lint_overflowing_range_endpoint<'tcx>( // overflowing and only by 1. if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max { cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| { - let mut err = lint.build(&format!("range endpoint is out of range for `{}`", ty)); + let mut err = lint.build(fluent::lint::range_endpoint_out_of_range); + err.set_arg("ty", ty); if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { use ast::{LitIntType, LitKind}; // We need to preserve the literal's suffix, @@ -153,7 +154,7 @@ fn lint_overflowing_range_endpoint<'tcx>( let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix); err.span_suggestion( parent_expr.span, - "use an inclusive range instead", + fluent::lint::suggestion, suggestion, Applicability::MachineApplicable, ); @@ -229,38 +230,35 @@ fn report_bin_hex_error( (t.name_str(), actually.to_string()) } }; - let mut err = lint.build(&format!("literal out of range for `{}`", t)); + let mut err = lint.build(fluent::lint::overflowing_bin_hex); if negative { // If the value is negative, // emits a note about the value itself, apart from the literal. - err.note(&format!( - "the literal `{}` (decimal `{}`) does not fit into \ - the type `{}`", - repr_str, val, t - )); - err.note(&format!("and the value `-{}` will become `{}{}`", repr_str, actually, t)); + err.note(fluent::lint::negative_note); + err.note(fluent::lint::negative_becomes_note); } else { - err.note(&format!( - "the literal `{}` (decimal `{}`) does not fit into \ - the type `{}` and will become `{}{}`", - repr_str, val, t, actually, t - )); + err.note(fluent::lint::positive_note); } if let Some(sugg_ty) = get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative) { + err.set_arg("suggestion_ty", sugg_ty); if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { let (sans_suffix, _) = repr_str.split_at(pos); err.span_suggestion( expr.span, - &format!("consider using the type `{}` instead", sugg_ty), + fluent::lint::suggestion, format!("{}{}", sans_suffix, sugg_ty), Applicability::MachineApplicable, ); } else { - err.help(&format!("consider using the type `{}` instead", sugg_ty)); + err.help(fluent::lint::help); } } + err.set_arg("ty", t); + err.set_arg("lit", repr_str); + err.set_arg("dec", val); + err.set_arg("actually", actually); err.emit(); }); } @@ -353,21 +351,23 @@ fn lint_int_literal<'tcx>( } cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - let mut err = lint.build(&format!("literal out of range for `{}`", t.name_str())); - err.note(&format!( - "the literal `{}` does not fit into the type `{}` whose range is `{}..={}`", + let mut err = lint.build(fluent::lint::overflowing_int); + err.set_arg("ty", t.name_str()); + err.set_arg( + "lit", cx.sess() .source_map() .span_to_snippet(lit.span) .expect("must get snippet from literal"), - t.name_str(), - min, - max, - )); + ); + err.set_arg("min", min); + err.set_arg("max", max); + err.note(fluent::lint::note); if let Some(sugg_ty) = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative) { - err.help(&format!("consider using the type `{}` instead", sugg_ty)); + err.set_arg("suggestion_ty", sugg_ty); + err.help(fluent::lint::help); } err.emit(); }); @@ -395,10 +395,10 @@ fn lint_uint_literal<'tcx>( hir::ExprKind::Cast(..) => { if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() { cx.struct_span_lint(OVERFLOWING_LITERALS, par_e.span, |lint| { - lint.build("only `u8` can be cast into `char`") + lint.build(fluent::lint::only_cast_u8_to_char) .span_suggestion( par_e.span, - "use a `char` literal instead", + fluent::lint::suggestion, format!("'\\u{{{:X}}}'", lit_val), Applicability::MachineApplicable, ) @@ -429,17 +429,18 @@ fn lint_uint_literal<'tcx>( return; } cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - lint.build(&format!("literal out of range for `{}`", t.name_str())) - .note(&format!( - "the literal `{}` does not fit into the type `{}` whose range is `{}..={}`", + lint.build(fluent::lint::overflowing_uint) + .set_arg("ty", t.name_str()) + .set_arg( + "lit", cx.sess() .source_map() .span_to_snippet(lit.span) .expect("must get snippet from literal"), - t.name_str(), - min, - max, - )) + ) + .set_arg("min", min) + .set_arg("max", max) + .note(fluent::lint::note) .emit(); }); } @@ -471,16 +472,16 @@ fn lint_literal<'tcx>( }; if is_infinite == Ok(true) { cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - lint.build(&format!("literal out of range for `{}`", t.name_str())) - .note(&format!( - "the literal `{}` does not fit into the type `{}` and will be converted to `{}::INFINITY`", + lint.build(fluent::lint::overflowing_literal) + .set_arg("ty", t.name_str()) + .set_arg( + "lit", cx.sess() .source_map() .span_to_snippet(lit.span) .expect("must get snippet from literal"), - t.name_str(), - t.name_str(), - )) + ) + .note(fluent::lint::note) .emit(); }); } @@ -501,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) && !check_limits(cx, binop, &l, &r) { cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| { - lint.build("comparison is useless due to type limits").emit(); + lint.build(fluent::lint::unused_comparisons).emit(); }); } } -- cgit 1.4.1-3-g733a5 From 14c3016583a0aad3e7a7dd87b2a13807b420b4e7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 28 Jun 2022 09:52:05 +0100 Subject: lint: port variant size difference diagnostics Signed-off-by: David Wood --- .../rustc_error_messages/locales/en-US/lint.ftl | 3 ++ compiler/rustc_errors/src/diagnostic.rs | 48 ++++++++++++++++++++++ compiler/rustc_lint/src/types.rs | 9 ++-- 3 files changed, 54 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index e9fa3de1b05..ba2490ab773 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -230,3 +230,6 @@ lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe lint-improper-ctypes-array-help = consider passing a pointer to the array lint-improper-ctypes-only-phantomdata = composed only of `PhantomData` + +lint-variant-size-differences = + enum variant is more than three times larger ({$largest} bytes) than the next largest diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 576248ae7c2..03e90b7b0d9 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -49,6 +49,54 @@ impl IntoDiagnosticArg for bool { } } +impl IntoDiagnosticArg for i8 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u8 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i16 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u16 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for i64 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + +impl IntoDiagnosticArg for u64 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + impl IntoDiagnosticArg for i128 { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Owned(self.to_string())) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 0b670764570..dd010040c12 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1387,12 +1387,9 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { VARIANT_SIZE_DIFFERENCES, enum_definition.variants[largest_index].span, |lint| { - lint.build(&format!( - "enum variant is more than three times \ - larger ({} bytes) than the next largest", - largest - )) - .emit(); + lint.build(fluent::lint::variant_size_differences) + .set_arg("largest", largest) + .emit(); }, ); } -- cgit 1.4.1-3-g733a5 From 10676418fa01d4f0ae8a34c57e4a71d7cd4c7cf2 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 28 Jun 2022 14:28:02 +0100 Subject: lint: port keyword idents diagnostics Signed-off-by: David Wood --- compiler/rustc_error_messages/locales/en-US/lint.ftl | 3 +++ compiler/rustc_errors/src/diagnostic.rs | 8 +++++++- compiler/rustc_lint/src/builtin.rs | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 4d1aca61105..134ee43f022 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -373,3 +373,6 @@ lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprec .suggestion = use `..=` for an inclusive range lint-builtin-unnameable-test-items = cannot test inner items + +lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition + .suggestion = you can use a raw identifier to stay compatible diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 03e90b7b0d9..fc619ad54cf 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -8,7 +8,7 @@ use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{edition::Edition, Span, DUMMY_SP}; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; @@ -115,6 +115,12 @@ impl IntoDiagnosticArg for String { } } +impl IntoDiagnosticArg for Edition { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + impl IntoDiagnosticArg for Symbol { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { self.to_ident_string().into_diagnostic_arg() diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index df30ea93708..a3ebc547544 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2033,10 +2033,12 @@ impl KeywordIdents { } cx.struct_span_lint(KEYWORD_IDENTS, ident.span, |lint| { - lint.build(&format!("`{}` is a keyword in the {} edition", ident, next_edition)) + lint.build(fluent::lint::builtin_keyword_idents) + .set_arg("kw", ident.clone()) + .set_arg("next", next_edition) .span_suggestion( ident.span, - "you can use a raw identifier to stay compatible", + fluent::lint::suggestion, format!("r#{}", ident), Applicability::MachineApplicable, ) -- cgit 1.4.1-3-g733a5 From bd8fe82138ba24f1c9f27bb64bf4269aabf9d54a Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 28 Jun 2022 14:40:11 +0100 Subject: lint: port incomplete features diagnostics Signed-off-by: David Wood --- compiler/rustc_error_messages/locales/en-US/lint.ftl | 4 ++++ compiler/rustc_errors/src/diagnostic.rs | 6 ++++++ compiler/rustc_lint/src/builtin.rs | 19 +++++-------------- 3 files changed, 15 insertions(+), 14 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index d21e3de1c4f..a1ad0320999 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -382,3 +382,7 @@ lint-builtin-explicit-outlives = outlives requirements can be inferred [one] this bound *[other] these bounds } + +lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes + .note = see issue #{$n} for more information + .help = consider using `min_{$name}` instead, which is more stable and complete diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index fc619ad54cf..3043ae827f9 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -115,6 +115,12 @@ impl IntoDiagnosticArg for String { } } +impl IntoDiagnosticArg for std::num::NonZeroU32 { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.to_string())) + } +} + impl IntoDiagnosticArg for Edition { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Owned(self.to_string())) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 1205b1c5e46..035cd358a91 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2347,23 +2347,14 @@ impl EarlyLintPass for IncompleteFeatures { .filter(|(&name, _)| features.incomplete(name)) .for_each(|(&name, &span)| { cx.struct_span_lint(INCOMPLETE_FEATURES, span, |lint| { - let mut builder = lint.build(&format!( - "the feature `{}` is incomplete and may not be safe to use \ - and/or cause compiler crashes", - name, - )); + let mut builder = lint.build(fluent::lint::builtin_incomplete_features); + builder.set_arg("name", name); if let Some(n) = rustc_feature::find_feature_issue(name, GateIssue::Language) { - builder.note(&format!( - "see issue #{} \ - for more information", - n, n, - )); + builder.set_arg("n", n); + builder.note(fluent::lint::note); } if HAS_MIN_FEATURES.contains(&name) { - builder.help(&format!( - "consider using `min_{}` instead, which is more stable and complete", - name, - )); + builder.help(fluent::lint::help); } builder.emit(); }) -- cgit 1.4.1-3-g733a5