about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-12-08 23:18:04 +0100
committerGitHub <noreply@github.com>2021-12-08 23:18:04 +0100
commitd26fc45e5bf170907cefcaa83c5b8e6cf6cb1351 (patch)
treeb6e9397a511ae314276d528c0113cbb311622847
parent2411cd7c7abd3a4d4aba657961ca1f940e1657bd (diff)
parentb9b4f549a45ccd6d5b5806153154c86e71e34bde (diff)
downloadrust-d26fc45e5bf170907cefcaa83c5b8e6cf6cb1351.tar.gz
rust-d26fc45e5bf170907cefcaa83c5b8e6cf6cb1351.zip
Rollup merge of #91337 - FabianWolff:issue-91227-misspelled-macro, r=nagisa
Add a suggestion if `macro_rules` is misspelled

Fixes #91227.
-rw-r--r--compiler/rustc_parse/src/parser/item.rs29
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.fixed13
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.rs13
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.stderr10
4 files changed, 61 insertions, 4 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 831c64e3faf..516e301ec3a 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -15,6 +15,7 @@ use rustc_ast::{MacArgs, MacCall, MacDelimiter};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
 use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
+use rustc_span::lev_distance::lev_distance;
 use rustc_span::source_map::{self, Span};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
@@ -410,10 +411,30 @@ impl<'a> Parser<'a> {
     fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
         let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
         self.expect(&token::Not)?; // `!`
-        let args = self.parse_mac_args()?; // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
-        self.eat_semi_for_macro_if_needed(&args);
-        self.complain_if_pub_macro(vis, false);
-        Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
+        match self.parse_mac_args() {
+            // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
+            Ok(args) => {
+                self.eat_semi_for_macro_if_needed(&args);
+                self.complain_if_pub_macro(vis, false);
+                Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
+            }
+
+            Err(mut err) => {
+                // Maybe the user misspelled `macro_rules` (issue #91227)
+                if self.token.is_ident()
+                    && path.segments.len() == 1
+                    && lev_distance("macro_rules", &path.segments[0].ident.to_string()) <= 3
+                {
+                    err.span_suggestion(
+                        path.span,
+                        "perhaps you meant to define a macro",
+                        "macro_rules".to_string(),
+                        Applicability::MachineApplicable,
+                    );
+                }
+                Err(err)
+            }
+        }
     }
 
     /// Recover if we parsed attributes and expected an item but there was none.
diff --git a/src/test/ui/parser/misspelled-macro-rules.fixed b/src/test/ui/parser/misspelled-macro-rules.fixed
new file mode 100644
index 00000000000..62be913d85f
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.fixed
@@ -0,0 +1,13 @@
+// Regression test for issue #91227.
+
+// run-rustfix
+
+#![allow(unused_macros)]
+
+macro_rules! thing {
+//~^ ERROR: expected one of
+//~| HELP: perhaps you meant to define a macro
+    () => {}
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/misspelled-macro-rules.rs b/src/test/ui/parser/misspelled-macro-rules.rs
new file mode 100644
index 00000000000..4290e6e5e4c
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.rs
@@ -0,0 +1,13 @@
+// Regression test for issue #91227.
+
+// run-rustfix
+
+#![allow(unused_macros)]
+
+marco_rules! thing {
+//~^ ERROR: expected one of
+//~| HELP: perhaps you meant to define a macro
+    () => {}
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/misspelled-macro-rules.stderr b/src/test/ui/parser/misspelled-macro-rules.stderr
new file mode 100644
index 00000000000..56df7123819
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.stderr
@@ -0,0 +1,10 @@
+error: expected one of `(`, `[`, or `{`, found `thing`
+  --> $DIR/misspelled-macro-rules.rs:7:14
+   |
+LL | marco_rules! thing {
+   | -----------  ^^^^^ expected one of `(`, `[`, or `{`
+   | |
+   | help: perhaps you meant to define a macro: `macro_rules`
+
+error: aborting due to previous error
+