diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d7cb159149d..7f7f36ca170 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -158,13 +158,15 @@ lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}` lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name} +lint_check_name_removed = lint `{$lint_name}` has been removed: {$reason} + +lint_check_name_renamed = lint `{$lint_name}` has been renamed to `{$replace}` + lint_check_name_unknown = unknown lint: `{$lint_name}` .help = did you mean: `{$suggestion}` lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` -lint_check_name_warning = {$msg} - lint_command_line_source = `forbid` lint level was set on command line lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike @@ -484,8 +486,11 @@ lint_redundant_semicolons = *[false] this semicolon } -lint_renamed_or_removed_lint = {$msg} +lint_removed_lint = lint `{$name}` has been removed: {$reason} + +lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}` .suggestion = use the new name + .help = use the new name `{$replace}` lint_requested_level = requested on the command line with `{$level} {$lint_name}` diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index aabefb729f3..9dfde84b552 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -17,8 +17,8 @@ use self::TargetLint::*; use crate::errors::{ - CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel, - UnsupportedGroup, + CheckNameDeprecated, CheckNameRemoved, CheckNameRenamed, CheckNameUnknown, + CheckNameUnknownTool, RequestedLevel, UnsupportedGroup, }; use crate::levels::LintLevelsBuilder; use crate::passes::{EarlyLintPassObject, LateLintPassObject}; @@ -124,9 +124,10 @@ pub enum CheckLintNameResult<'a> { NoLint(Option), /// The lint refers to a tool that has not been registered. NoTool, - /// The lint is either renamed or removed. This is the warning - /// message, and an optional new name (`None` if removed). - Warning(String, Option), + /// The lint has been renamed to a new name. + Renamed(String), + /// The lint has been removed due to the given reason. + Removed(String), /// The lint is from a tool. If the Option is None, then either /// the lint does not exist in the tool or the code was not /// compiled with the tool and therefore the lint was never @@ -342,25 +343,32 @@ impl LintStore { sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() }); return; } - let lint_name = lint_name.to_string(); match self.check_lint_name(lint_name_only, tool_name, registered_tools) { - CheckLintNameResult::Warning(msg, _) => { - sess.emit_warning(CheckNameWarning { - msg, + CheckLintNameResult::Renamed(replace) => { + sess.emit_warning(CheckNameRenamed { + lint_name, + replace: &replace, + sub: RequestedLevel { level, lint_name }, + }); + } + CheckLintNameResult::Removed(reason) => { + sess.emit_warning(CheckNameRemoved { + lint_name, + reason: &reason, sub: RequestedLevel { level, lint_name }, }); } CheckLintNameResult::NoLint(suggestion) => { sess.emit_err(CheckNameUnknown { - lint_name: lint_name.clone(), + lint_name, suggestion, sub: RequestedLevel { level, lint_name }, }); } CheckLintNameResult::Tool(Err((Some(_), new_name))) => { sess.emit_warning(CheckNameDeprecated { - lint_name: lint_name.clone(), - new_name, + lint_name, + new_name: &new_name, sub: RequestedLevel { level, lint_name }, }); } @@ -445,14 +453,8 @@ impl LintStore { } } match self.by_name.get(&complete_name) { - Some(Renamed(new_name, _)) => CheckLintNameResult::Warning( - format!("lint `{complete_name}` has been renamed to `{new_name}`"), - Some(new_name.to_owned()), - ), - Some(Removed(reason)) => CheckLintNameResult::Warning( - format!("lint `{complete_name}` has been removed: {reason}"), - None, - ), + Some(Renamed(new_name, _)) => CheckLintNameResult::Renamed(new_name.to_string()), + Some(Removed(reason)) => CheckLintNameResult::Removed(reason.to_string()), None => match self.lint_groups.get(&*complete_name) { // If neither the lint, nor the lint group exists check if there is a `clippy::` // variant of this lint diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 68167487a1b..607875b3faa 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -91,9 +91,9 @@ pub struct BuiltinEllipsisInclusiveRangePatterns { #[derive(Subdiagnostic)] #[note(lint_requested_level)] -pub struct RequestedLevel { +pub struct RequestedLevel<'a> { pub level: Level, - pub lint_name: String, + pub lint_name: &'a str, } #[derive(Diagnostic)] @@ -102,13 +102,13 @@ pub struct UnsupportedGroup { pub lint_group: String, } -pub struct CheckNameUnknown { - pub lint_name: String, +pub struct CheckNameUnknown<'a> { + pub lint_name: &'a str, pub suggestion: Option, - pub sub: RequestedLevel, + pub sub: RequestedLevel<'a>, } -impl IntoDiagnostic<'_> for CheckNameUnknown { +impl IntoDiagnostic<'_> for CheckNameUnknown<'_> { fn into_diagnostic( self, handler: &Handler, @@ -127,25 +127,35 @@ impl IntoDiagnostic<'_> for CheckNameUnknown { #[derive(Diagnostic)] #[diag(lint_check_name_unknown_tool, code = "E0602")] -pub struct CheckNameUnknownTool { +pub struct CheckNameUnknownTool<'a> { pub tool_name: Symbol, #[subdiagnostic] - pub sub: RequestedLevel, + pub sub: RequestedLevel<'a>, } #[derive(Diagnostic)] -#[diag(lint_check_name_warning)] -pub struct CheckNameWarning { - pub msg: String, +#[diag(lint_check_name_renamed)] +pub struct CheckNameRenamed<'a> { + pub lint_name: &'a str, + pub replace: &'a str, #[subdiagnostic] - pub sub: RequestedLevel, + pub sub: RequestedLevel<'a>, +} + +#[derive(Diagnostic)] +#[diag(lint_check_name_removed)] +pub struct CheckNameRemoved<'a> { + pub lint_name: &'a str, + pub reason: &'a str, + #[subdiagnostic] + pub sub: RequestedLevel<'a>, } #[derive(Diagnostic)] #[diag(lint_check_name_deprecated)] -pub struct CheckNameDeprecated { - pub lint_name: String, - pub new_name: String, +pub struct CheckNameDeprecated<'a> { + pub lint_name: &'a str, + pub new_name: &'a str, #[subdiagnostic] - pub sub: RequestedLevel, + pub sub: RequestedLevel<'a>, } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 0a40d17f98e..f58782c0f22 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -4,8 +4,8 @@ use crate::{ fluent_generated as fluent, late::unerased_lint_store, lints::{ - DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAttributeLint, - RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion, + DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAttributeLint, RemovedLint, + RenamedLint, RenamedLintSuggestion, UnknownLint, UnknownLintSuggestion, }, }; use rustc_ast as ast; @@ -915,18 +915,26 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { _ if !self.warn_about_weird_lints => {} - CheckLintNameResult::Warning(msg, renamed) => { + CheckLintNameResult::Renamed(new_name) => { let suggestion = - renamed.as_ref().map(|replace| RenamedOrRemovedLintSuggestion { - suggestion: sp, - replace: replace.as_str(), - }); + RenamedLintSuggestion { suggestion: sp, replace: new_name.as_str() }; + let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); self.emit_spanned_lint( RENAMED_AND_REMOVED_LINTS, sp.into(), - RenamedOrRemovedLint { msg, suggestion }, + RenamedLint { name: name.as_str(), suggestion }, ); } + + CheckLintNameResult::Removed(reason) => { + let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); + self.emit_spanned_lint( + RENAMED_AND_REMOVED_LINTS, + sp.into(), + RemovedLint { name: name.as_str(), reason: reason.as_str() }, + ); + } + CheckLintNameResult::NoLint(suggestion) => { let name = if let Some(tool_ident) = tool_ident { format!("{}::{}", tool_ident.name, name) @@ -945,7 +953,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // If this lint was renamed, apply the new lint instead of ignoring the attribute. // This happens outside of the match because the new lint should be applied even if // we don't warn about the name change. - if let CheckLintNameResult::Warning(_, Some(new_name)) = lint_result { + if let CheckLintNameResult::Renamed(new_name) = lint_result { // Ignore any errors or warnings that happen because the new name is inaccurate // NOTE: `new_name` already includes the tool name, so we don't have to add it again. if let CheckLintNameResult::Ok(ids) = diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 993c576d697..0e942d774a7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1012,23 +1012,29 @@ pub struct DeprecatedLintName<'a> { pub replace: &'a str, } -// FIXME: Non-translatable msg #[derive(LintDiagnostic)] -#[diag(lint_renamed_or_removed_lint)] -pub struct RenamedOrRemovedLint<'a> { - pub msg: &'a str, +#[diag(lint_renamed_lint)] +pub struct RenamedLint<'a> { + pub name: &'a str, #[subdiagnostic] - pub suggestion: Option>, + pub suggestion: RenamedLintSuggestion<'a>, } #[derive(Subdiagnostic)] #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")] -pub struct RenamedOrRemovedLintSuggestion<'a> { +pub struct RenamedLintSuggestion<'a> { #[primary_span] pub suggestion: Span, pub replace: &'a str, } +#[derive(LintDiagnostic)] +#[diag(lint_removed_lint)] +pub struct RemovedLint<'a> { + pub name: &'a str, + pub reason: &'a str, +} + #[derive(LintDiagnostic)] #[diag(lint_unknown_lint)] pub struct UnknownLint {