Skip to content

Commit d26fc45

Browse files
authored
Rollup merge of rust-lang#91337 - FabianWolff:issue-91227-misspelled-macro, r=nagisa
Add a suggestion if `macro_rules` is misspelled Fixes rust-lang#91227.
2 parents 2411cd7 + b9b4f54 commit d26fc45

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

compiler/rustc_parse/src/parser/item.rs

+25-4
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

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

419440
/// Recover if we parsed attributes and expected an item but there was none.
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() {}
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() {}
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)