diff options
| author | Fabian Wolff <fabian.wolff@alumni.ethz.ch> | 2021-11-28 23:10:37 +0100 |
|---|---|---|
| committer | Fabian Wolff <fabian.wolff@alumni.ethz.ch> | 2021-11-28 23:10:37 +0100 |
| commit | b9b4f549a45ccd6d5b5806153154c86e71e34bde (patch) | |
| tree | 8d8b903cc89081dd9e387e28e02e06fa169be0e1 | |
| parent | 5fd3a5c7c175f228afaf5fc6ff00c177b83d8055 (diff) | |
| download | rust-b9b4f549a45ccd6d5b5806153154c86e71e34bde.tar.gz rust-b9b4f549a45ccd6d5b5806153154c86e71e34bde.zip | |
Add a suggestion if `macro_rules` is misspelled
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/parser/misspelled-macro-rules.fixed | 13 | ||||
| -rw-r--r-- | src/test/ui/parser/misspelled-macro-rules.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/parser/misspelled-macro-rules.stderr | 10 |
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 24a8df49ac7..aa572eaf162 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}; @@ -407,10 +408,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 + |
