about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/context.rs39
-rw-r--r--compiler/rustc_lint/src/levels.rs5
2 files changed, 30 insertions, 14 deletions
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 0f40324acb1..c4df0acbbb0 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -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 {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 37bdc878b16..fc8f84461f9 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -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(