about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-15 07:16:48 +0200
committerGitHub <noreply@github.com>2024-05-15 07:16:48 +0200
commitf7c293442074ec4ef5d5114700c37ad62ecf0834 (patch)
tree93fad63da28858b36289429b901b6bafc14fca60
parenta8ff937b07d4b15394032e5cc8c786988669cdb1 (diff)
parent18d7411719c954fdd72307ce96fc9b3bf891bc7f (diff)
downloadrust-f7c293442074ec4ef5d5114700c37ad62ecf0834.tar.gz
rust-f7c293442074ec4ef5d5114700c37ad62ecf0834.zip
Rollup merge of #125132 - mejrs:diag, r=compiler-errors
Add `on_unimplemented" typo suggestions
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs8
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_resolve/src/macros.rs20
-rw-r--r--tests/ui/diagnostic_namespace/suggest_typos.rs18
-rw-r--r--tests/ui/diagnostic_namespace/suggest_typos.stderr40
5 files changed, 85 insertions, 5 deletions
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 8458b539335..5ad3ff71a6d 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -347,5 +347,13 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
                 "reduce the glob import's visibility or increase visibility of imported items",
             );
         }
+        BuiltinLintDiag::MaybeTypo { span, name } => {
+            diag.span_suggestion_verbose(
+                span,
+                "an attribute with a similar name exists",
+                name,
+                Applicability::MachineApplicable,
+            );
+        }
     }
 }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index ed165188787..e06e3e9b805 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -663,6 +663,10 @@ pub enum BuiltinLintDiag {
         span: Span,
         max_vis: String,
     },
+    MaybeTypo {
+        span: Span,
+        name: Symbol,
+    },
 }
 
 /// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 35bf3f761df..e3cfe6a6e05 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -29,6 +29,7 @@ use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
 use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::feature_err;
+use rustc_span::edit_distance::edit_distance;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{self, ExpnData, ExpnKind, LocalExpnId};
 use rustc_span::hygiene::{AstPass, MacroKind};
@@ -568,15 +569,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
-            && path.segments.len() >= 2
-            && path.segments[0].ident.name == sym::diagnostic
-            && path.segments[1].ident.name != sym::on_unimplemented
+            && let [namespace, attribute, ..] = &*path.segments
+            && namespace.ident.name == sym::diagnostic
+            && attribute.ident.name != sym::on_unimplemented
         {
-            self.tcx.sess.psess.buffer_lint(
+            let distance =
+                edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5);
+
+            let help = if distance.is_some() {
+                BuiltinLintDiag::MaybeTypo { span: attribute.span(), name: sym::on_unimplemented }
+            } else {
+                BuiltinLintDiag::Normal
+            };
+            self.tcx.sess.psess.buffer_lint_with_diagnostic(
                 UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                path.segments[1].span(),
+                attribute.span(),
                 node_id,
                 "unknown diagnostic attribute",
+                help,
             );
         }
 
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.rs b/tests/ui/diagnostic_namespace/suggest_typos.rs
new file mode 100644
index 00000000000..b25f097a8ad
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/suggest_typos.rs
@@ -0,0 +1,18 @@
+#![deny(unknown_or_malformed_diagnostic_attributes)]
+
+#[diagnostic::onunimplemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait X{}
+
+#[diagnostic::un_onimplemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait Y{}
+
+#[diagnostic::on_implemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait Z{}
+
+fn main(){}
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr
new file mode 100644
index 00000000000..307311258f2
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr
@@ -0,0 +1,40 @@
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:3:15
+   |
+LL | #[diagnostic::onunimplemented]
+   |               ^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/suggest_typos.rs:1:9
+   |
+LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:8:15
+   |
+LL | #[diagnostic::un_onimplemented]
+   |               ^^^^^^^^^^^^^^^^
+   |
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:13:15
+   |
+LL | #[diagnostic::on_implemented]
+   |               ^^^^^^^^^^^^^^
+   |
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: aborting due to 3 previous errors
+