@@ -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
@@ -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.
0 commit comments