Skip to content

Commit

Permalink
feat(rustc_lint): make CheckLintName respect lint level
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanglo committed Aug 30, 2023
1 parent cdbad43 commit a11805a
Show file tree
Hide file tree
Showing 24 changed files with 191 additions and 171 deletions.
11 changes: 2 additions & 9 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,6 @@ lint_builtin_unused_doc_comment = unused doc comment
lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
.suggestion = use `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_command_line_source = `forbid` lint level was set on command line
Expand All @@ -187,6 +178,7 @@ lint_default_source = `forbid` lint level is the default for {$id}
lint_deprecated_lint_name =
lint name `{$name}` is deprecated and may not have an effect in the future.
.suggestion = change it to
.help = change it to {$replace}
lint_diag_out_of_impl =
diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
Expand Down Expand Up @@ -528,6 +520,7 @@ lint_unknown_gated_lint =
lint_unknown_lint =
unknown lint: `{$name}`
.suggestion = did you mean
.help = did you mean: `{$replace}`
lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`
.help = add `#![register_tool({$tool_name})]` to the crate root
Expand Down
54 changes: 1 addition & 53 deletions compiler/rustc_lint/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::fluent_generated as fluent;
use rustc_errors::{
AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic, SubdiagnosticMessage,
};
use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_session::lint::Level;
use rustc_span::{Span, Symbol};
Expand Down Expand Up @@ -102,60 +100,10 @@ pub struct UnsupportedGroup {
pub lint_group: String,
}

pub struct CheckNameUnknown<'a> {
pub lint_name: &'a str,
pub suggestion: Option<Symbol>,
pub sub: RequestedLevel<'a>,
}

impl IntoDiagnostic<'_> for CheckNameUnknown<'_> {
fn into_diagnostic(
self,
handler: &Handler,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = handler.struct_err(fluent::lint_check_name_unknown);
diag.code(rustc_errors::error_code!(E0602));
if let Some(suggestion) = self.suggestion {
diag.help(fluent::lint_help);
diag.set_arg("suggestion", suggestion);
}
diag.set_arg("lint_name", self.lint_name);
diag.subdiagnostic(self.sub);
diag
}
}

#[derive(Diagnostic)]
#[diag(lint_check_name_unknown_tool, code = "E0602")]
pub struct CheckNameUnknownTool<'a> {
pub tool_name: Symbol,
#[subdiagnostic]
pub sub: RequestedLevel<'a>,
}

#[derive(Diagnostic)]
#[diag(lint_check_name_renamed)]
pub struct CheckNameRenamed<'a> {
pub lint_name: &'a str,
pub replace: &'a str,
#[subdiagnostic]
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<'a> {
pub lint_name: &'a str,
pub new_name: &'a str,
#[subdiagnostic]
pub sub: RequestedLevel<'a>,
}
84 changes: 38 additions & 46 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::errors::{
CheckNameDeprecated, CheckNameRemoved, CheckNameRenamed, CheckNameUnknown,
CheckNameUnknownTool, RequestedLevel, UnsupportedGroup,
use crate::errors::{CheckNameUnknownTool, RequestedLevel, UnsupportedGroup};
use crate::lints::{
DeprecatedLintNameFromCommandLine, RemovedLintFromCommandLine, RenamedLintFromCommandLine,
UnknownLintFromCommandLine,
};
use crate::{
builtin::MISSING_DOCS,
Expand Down Expand Up @@ -564,33 +565,32 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
self.sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
}
match self.store.check_lint_name(lint_name_only, tool_name, self.registered_tools) {
CheckLintNameResult::Renamed(replace) => {
self.sess.emit_warning(CheckNameRenamed {
lint_name,
replace: &replace,
sub: RequestedLevel { level, lint_name },
});
CheckLintNameResult::Renamed(ref replace) => {
let name = lint_name.as_str();
let suggestion = RenamedLintSuggestion::WithoutSpan { replace };
let requested_level = RequestedLevel { level, lint_name };
let lint = RenamedLintFromCommandLine { name, suggestion, requested_level };
self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint);
}
CheckLintNameResult::Removed(reason) => {
self.sess.emit_warning(CheckNameRemoved {
lint_name,
reason: &reason,
sub: RequestedLevel { level, lint_name },
});
CheckLintNameResult::Removed(ref reason) => {
let name = lint_name.as_str();
let requested_level = RequestedLevel { level, lint_name };
let lint = RemovedLintFromCommandLine { name, reason, requested_level };
self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint);
}
CheckLintNameResult::NoLint(suggestion) => {
self.sess.emit_err(CheckNameUnknown {
lint_name,
suggestion,
sub: RequestedLevel { level, lint_name },
});
let name = lint_name.clone();
let suggestion =
suggestion.map(|replace| UnknownLintSuggestion::WithoutSpan { replace });
let requested_level = RequestedLevel { level, lint_name };
let lint = UnknownLintFromCommandLine { name, suggestion, requested_level };
self.emit_lint(UNKNOWN_LINTS, lint);
}
CheckLintNameResult::Tool(Err((Some(_), new_name))) => {
self.sess.emit_warning(CheckNameDeprecated {
lint_name,
new_name: &new_name,
sub: RequestedLevel { level, lint_name },
});
CheckLintNameResult::Tool(Err((Some(_), ref replace))) => {
let name = lint_name.clone();
let requested_level = RequestedLevel { level, lint_name };
let lint = DeprecatedLintNameFromCommandLine { name, replace, requested_level };
self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint);
}
CheckLintNameResult::NoTool => {
self.sess.emit_err(CheckNameUnknownTool {
Expand Down Expand Up @@ -963,24 +963,18 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {

_ if !self.warn_about_weird_lints => {}

CheckLintNameResult::Renamed(new_name) => {
CheckLintNameResult::Renamed(ref replace) => {
let suggestion =
RenamedLintSuggestion { suggestion: sp, replace: new_name.as_str() };
RenamedLintSuggestion::WithSpan { suggestion: sp, replace };
let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
self.emit_spanned_lint(
RENAMED_AND_REMOVED_LINTS,
sp.into(),
RenamedLint { name: name.as_str(), suggestion },
);
let lint = RenamedLint { name: name.as_str(), suggestion };
self.emit_spanned_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}

CheckLintNameResult::Removed(reason) => {
CheckLintNameResult::Removed(ref 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() },
);
let lint = RemovedLint { name: name.as_str(), reason };
self.emit_spanned_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint);
}

CheckLintNameResult::NoLint(suggestion) => {
Expand All @@ -989,13 +983,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
} else {
name.to_string()
};
let suggestion = suggestion
.map(|replace| UnknownLintSuggestion { suggestion: sp, replace });
self.emit_spanned_lint(
UNKNOWN_LINTS,
sp.into(),
UnknownLint { name, suggestion },
);
let suggestion = suggestion.map(|replace| {
UnknownLintSuggestion::WithSpan { suggestion: sp, replace }
});
let lint = UnknownLint { name, suggestion };
self.emit_spanned_lint(UNKNOWN_LINTS, sp.into(), lint);
}
}
// If this lint was renamed, apply the new lint instead of ignoring the attribute.
Expand Down
68 changes: 58 additions & 10 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
use std::num::NonZeroU32;

use crate::errors::RequestedLevel;
use crate::fluent_generated as fluent;
use rustc_errors::{
AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString,
Expand Down Expand Up @@ -1012,6 +1013,16 @@ pub struct DeprecatedLintName<'a> {
pub replace: &'a str,
}

#[derive(LintDiagnostic)]
#[diag(lint_deprecated_lint_name)]
#[help]
pub struct DeprecatedLintNameFromCommandLine<'a> {
pub name: String,
pub replace: &'a str,
#[subdiagnostic]
pub requested_level: RequestedLevel<'a>,
}

#[derive(LintDiagnostic)]
#[diag(lint_renamed_lint)]
pub struct RenamedLint<'a> {
Expand All @@ -1021,11 +1032,25 @@ pub struct RenamedLint<'a> {
}

#[derive(Subdiagnostic)]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
pub struct RenamedLintSuggestion<'a> {
#[primary_span]
pub suggestion: Span,
pub replace: &'a str,
pub enum RenamedLintSuggestion<'a> {
#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
WithSpan {
#[primary_span]
suggestion: Span,
replace: &'a str,
},
#[help(lint_help)]
WithoutSpan { replace: &'a str },
}

#[derive(LintDiagnostic)]
#[diag(lint_renamed_lint)]
pub struct RenamedLintFromCommandLine<'a> {
pub name: &'a str,
#[subdiagnostic]
pub suggestion: RenamedLintSuggestion<'a>,
#[subdiagnostic]
pub requested_level: RequestedLevel<'a>,
}

#[derive(LintDiagnostic)]
Expand All @@ -1035,6 +1060,15 @@ pub struct RemovedLint<'a> {
pub reason: &'a str,
}

#[derive(LintDiagnostic)]
#[diag(lint_removed_lint)]
pub struct RemovedLintFromCommandLine<'a> {
pub name: &'a str,
pub reason: &'a str,
#[subdiagnostic]
pub requested_level: RequestedLevel<'a>,
}

#[derive(LintDiagnostic)]
#[diag(lint_unknown_lint)]
pub struct UnknownLint {
Expand All @@ -1044,11 +1078,25 @@ pub struct UnknownLint {
}

#[derive(Subdiagnostic)]
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
pub struct UnknownLintSuggestion {
#[primary_span]
pub suggestion: Span,
pub replace: Symbol,
pub enum UnknownLintSuggestion {
#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
WithSpan {
#[primary_span]
suggestion: Span,
replace: Symbol,
},
#[help(lint_help)]
WithoutSpan { replace: Symbol },
}

#[derive(LintDiagnostic)]
#[diag(lint_unknown_lint, code = "E0602")]
pub struct UnknownLintFromCommandLine<'a> {
pub name: String,
#[subdiagnostic]
pub suggestion: Option<UnknownLintSuggestion>,
#[subdiagnostic]
pub requested_level: RequestedLevel<'a>,
}

#[derive(LintDiagnostic)]
Expand Down
10 changes: 7 additions & 3 deletions tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
warning: lint name `test_lint` is deprecated and may not have an effect in the future.
|
= help: change it to clippy::test_lint
= note: requested on the command line with `-A test_lint`
= note: `#[warn(renamed_and_removed_lints)]` on by default

warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
warning: lint name `test_lint` is deprecated and may not have an effect in the future.
|
= help: change it to clippy::test_lint
= note: requested on the command line with `-A test_lint`

warning: item is named 'lintme'
Expand All @@ -22,8 +25,9 @@ LL | #![plugin(lint_tool_test)]
|
= note: `#[warn(deprecated)]` on by default

warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
warning: lint name `test_lint` is deprecated and may not have an effect in the future.
|
= help: change it to clippy::test_lint
= note: requested on the command line with `-A test_lint`

warning: 5 warnings emitted
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/error-codes/E0602.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// compile-flags:-D bogus
// check-pass

// error-pattern:E0602
// error-pattern:requested on the command line with `-D bogus`
// error-pattern:`#[warn(unknown_lints)]` on by default

fn main() {}
11 changes: 8 additions & 3 deletions tests/ui/error-codes/E0602.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
error[E0602]: unknown lint: `bogus`
warning[E0602]: unknown lint: `bogus`
|
= note: requested on the command line with `-D bogus`
= note: `#[warn(unknown_lints)]` on by default

error[E0602]: unknown lint: `bogus`
warning[E0602]: unknown lint: `bogus`
|
= note: requested on the command line with `-D bogus`

error: aborting due to 2 previous errors
warning[E0602]: unknown lint: `bogus`
|
= note: requested on the command line with `-D bogus`

warning: 3 warnings emitted

For more information about this error, try `rustc --explain E0602`.
6 changes: 5 additions & 1 deletion tests/ui/lint/cli-unknown-force-warn.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Checks that rustc correctly errors when passed an invalid lint with
// `--force-warn`. This is a regression test for issue #86958.
//

// check-pass
// compile-flags: --force-warn foo-qux

// error-pattern: unknown lint: `foo_qux`
// error-pattern: requested on the command line with `--force-warn foo_qux`
// error-pattern: `#[warn(unknown_lints)]` on by default

fn main() {}
Loading

0 comments on commit a11805a

Please sign in to comment.