Skip to content

Commit

Permalink
Don't make tools responsible for checking unknown and renamed lints
Browse files Browse the repository at this point in the history
Previously, clippy (and any other tool emitting lints) had to have their
own separate UNKNOWN_LINTS pass, because the compiler assumed any tool
lint could be valid. Now, as long as any lint starting with the tool
prefix exists, the compiler will warn when an unknown lint is present.
  • Loading branch information
jyn514 committed Jan 15, 2021
1 parent e48eb37 commit 5053db7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
39 changes: 25 additions & 14 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,23 @@ impl LintStore {
lint_name.to_string()
};
// If the lint was scoped with `tool::` check if the tool lint exists
if tool_name.is_some() {
if let Some(tool_name) = tool_name {
match self.by_name.get(&complete_name) {
None => match self.lint_groups.get(&*complete_name) {
None => return CheckLintNameResult::Tool(Err((None, String::new()))),
// If the lint isn't registered, there are two possibilities:
None => {
// 1. The tool is currently running, so this lint really doesn't exist.
// FIXME: should this handle tools that never register a lint, like rustfmt?
tracing::debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
let tool_prefix = format!("{}::", tool_name);
return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
self.no_lint_suggestion(&complete_name)
} else {
// 2. The tool isn't currently running, so no lints will be registered.
// To avoid giving a false positive, ignore all unknown lints.
CheckLintNameResult::Tool(Err((None, String::new())))
};
}
Some(LintGroup { lint_ids, .. }) => {
return CheckLintNameResult::Tool(Ok(&lint_ids));
}
Expand Down Expand Up @@ -398,6 +411,15 @@ impl LintStore {
}
}

fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> {
let symbols = self.by_name.keys().map(|name| Symbol::intern(&name)).collect::<Vec<_>>();

let suggestion =
find_best_match_for_name(&symbols, Symbol::intern(&lint_name.to_lowercase()), None);

CheckLintNameResult::NoLint(suggestion)
}

fn check_tool_name_for_backwards_compat(
&self,
lint_name: &str,
Expand All @@ -407,18 +429,7 @@ impl LintStore {
match self.by_name.get(&complete_name) {
None => match self.lint_groups.get(&*complete_name) {
// Now we are sure, that this lint exists nowhere
None => {
let symbols =
self.by_name.keys().map(|name| Symbol::intern(&name)).collect::<Vec<_>>();

let suggestion = find_best_match_for_name(
&symbols,
Symbol::intern(&lint_name.to_lowercase()),
None,
);

CheckLintNameResult::NoLint(suggestion)
}
None => self.no_lint_suggestion(lint_name),
Some(LintGroup { lint_ids, depr, .. }) => {
// Reaching this would be weird, but let's cover this case anyway
if let Some(LintAlias { name, silent }) = depr {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ impl<'s> LintLevelsBuilder<'s> {
src,
Some(li.span().into()),
|lint| {
let name = if let Some(tool_name) = tool_name {
format!("{}::{}", tool_name, name)
} else {
name.to_string()
};
let mut db = lint.build(&format!("unknown lint: `{}`", name));
if let Some(suggestion) = suggestion {
db.span_suggestion(
Expand Down

0 comments on commit 5053db7

Please sign in to comment.