Skip to content

Commit b9b4f54

Browse files
committed
Add a suggestion if macro_rules is misspelled
1 parent 5fd3a5c commit b9b4f54

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

compiler/rustc_parse/src/parser/item.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_ast::{MacArgs, MacCall, MacDelimiter};
1515
use rustc_ast_pretty::pprust;
1616
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
1717
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
18+
use rustc_span::lev_distance::lev_distance;
1819
use rustc_span::source_map::{self, Span};
1920
use rustc_span::symbol::{kw, sym, Ident, Symbol};
2021

@@ -407,10 +408,30 @@ impl<'a> Parser<'a> {
407408
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
408409
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
409410
self.expect(&token::Not)?; // `!`
410-
let args = self.parse_mac_args()?; // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
411-
self.eat_semi_for_macro_if_needed(&args);
412-
self.complain_if_pub_macro(vis, false);
413-
Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
411+
match self.parse_mac_args() {
412+
// `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
413+
Ok(args) => {
414+
self.eat_semi_for_macro_if_needed(&args);
415+
self.complain_if_pub_macro(vis, false);
416+
Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
417+
}
418+
419+
Err(mut err) => {
420+
// Maybe the user misspelled `macro_rules` (issue #91227)
421+
if self.token.is_ident()
422+
&& path.segments.len() == 1
423+
&& lev_distance("macro_rules", &path.segments[0].ident.to_string()) <= 3
424+
{
425+
err.span_suggestion(
426+
path.span,
427+
"perhaps you meant to define a macro",
428+
"macro_rules".to_string(),
429+
Applicability::MachineApplicable,
430+
);
431+
}
432+
Err(err)
433+
}
434+
}
414435
}
415436

416437
/// Recover if we parsed attributes and expected an item but there was none.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Regression test for issue #91227.
2+
3+
// run-rustfix
4+
5+
#![allow(unused_macros)]
6+
7+
macro_rules! thing {
8+
//~^ ERROR: expected one of
9+
//~| HELP: perhaps you meant to define a macro
10+
() => {}
11+
}
12+
13+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Regression test for issue #91227.
2+
3+
// run-rustfix
4+
5+
#![allow(unused_macros)]
6+
7+
marco_rules! thing {
8+
//~^ ERROR: expected one of
9+
//~| HELP: perhaps you meant to define a macro
10+
() => {}
11+
}
12+
13+
fn main() {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: expected one of `(`, `[`, or `{`, found `thing`
2+
--> $DIR/misspelled-macro-rules.rs:7:14
3+
|
4+
LL | marco_rules! thing {
5+
| ----------- ^^^^^ expected one of `(`, `[`, or `{`
6+
| |
7+
| help: perhaps you meant to define a macro: `macro_rules`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)