@@ -15,6 +15,7 @@ use rustc_ast::{MacArgs, MacCall, MacDelimiter};
15
15
use rustc_ast_pretty:: pprust;
16
16
use rustc_errors:: { struct_span_err, Applicability , PResult , StashKey } ;
17
17
use rustc_span:: edition:: { Edition , LATEST_STABLE_EDITION } ;
18
+ use rustc_span:: lev_distance:: lev_distance;
18
19
use rustc_span:: source_map:: { self , Span } ;
19
20
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
20
21
@@ -410,10 +411,30 @@ impl<'a> Parser<'a> {
410
411
fn parse_item_macro ( & mut self , vis : & Visibility ) -> PResult < ' a , MacCall > {
411
412
let path = self . parse_path ( PathStyle :: Mod ) ?; // `foo::bar`
412
413
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
+ }
417
438
}
418
439
419
440
/// Recover if we parsed attributes and expected an item but there was none.
0 commit comments