@@ -15,6 +15,7 @@ use rustc_ast::{MacArgs, MacCall, MacDelimiter};
1515use rustc_ast_pretty:: pprust;
1616use rustc_errors:: { struct_span_err, Applicability , PResult , StashKey } ;
1717use rustc_span:: edition:: { Edition , LATEST_STABLE_EDITION } ;
18+ use rustc_span:: lev_distance:: lev_distance;
1819use rustc_span:: source_map:: { self , Span } ;
1920use 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.
0 commit comments