Don't make tools responsible for checking unknown and renamed lints
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.
This commit is contained in:
parent
e48eb37b94
commit
5053db7c00
@ -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));
|
||||
}
|
||||
@ -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,
|
||||
@ -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 {
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user