@@ -2036,23 +2036,26 @@ impl<'a> Parser<'a> {
20362036
20372037 /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
20382038 fn is_macro_rules_item ( & mut self ) -> IsMacroRulesItem {
2039- if self . check_keyword ( kw:: MacroRules ) {
2040- let macro_rules_span = self . token . span ;
2041-
2042- if self . look_ahead ( 1 , |t| * t == token:: Not ) && self . look_ahead ( 2 , |t| t. is_ident ( ) ) {
2043- return IsMacroRulesItem :: Yes { has_bang : true } ;
2044- } else if self . look_ahead ( 1 , |t| ( t. is_ident ( ) ) ) {
2045- // macro_rules foo
2046- self . sess . emit_err ( errors:: MacroRulesMissingBang {
2047- span : macro_rules_span,
2048- hi : macro_rules_span. shrink_to_hi ( ) ,
2049- } ) ;
2039+ if !self . check_keyword ( kw:: MacroRules ) {
2040+ return IsMacroRulesItem :: No ;
2041+ }
2042+
2043+ let macro_rules_span = self . token . span ;
2044+ let has_bang = self . look_ahead ( 1 , |t| * t == token:: Not ) ;
20502045
2051- return IsMacroRulesItem :: Yes { has_bang : false } ;
2046+ // macro_rules foo
2047+ if !has_bang {
2048+ if !self . look_ahead ( 1 , |t| ( t. is_ident ( ) ) ) {
2049+ return IsMacroRulesItem :: No ;
20522050 }
2051+
2052+ self . sess . emit_err ( errors:: MacroRulesMissingBang {
2053+ span : macro_rules_span,
2054+ hi : macro_rules_span. shrink_to_hi ( ) ,
2055+ } ) ;
20532056 }
20542057
2055- IsMacroRulesItem :: No
2058+ IsMacroRulesItem :: Yes { has_bang }
20562059 }
20572060
20582061 /// Parses a `macro_rules! foo { ... }` declarative macro.
@@ -2066,7 +2069,34 @@ impl<'a> Parser<'a> {
20662069 if has_bang {
20672070 self . expect ( & token:: Not ) ?; // `!`
20682071 }
2069- let ident = self . parse_ident ( ) ?;
2072+
2073+ let ident = match self . parse_ident ( ) {
2074+ Ok ( ident) => ident,
2075+ Err ( mut err) => {
2076+ if let TokenKind :: OpenDelim ( Delimiter :: Parenthesis ) = self . token . kind
2077+ && let Some ( ( Ident { name, .. } , _) ) = self . look_ahead ( 1 , |token| token. ident ( ) )
2078+ && let Some ( closing_span) = self . look_ahead ( 2 , |token| {
2079+ ( token. kind == TokenKind :: CloseDelim ( Delimiter :: Parenthesis ) )
2080+ . then_some ( token. span )
2081+ } )
2082+ {
2083+ err. span_suggestion (
2084+ self . token . span . with_hi ( closing_span. hi ( ) ) ,
2085+ "try removing the parenthesis around the name for this `macro_rules!`" ,
2086+ name,
2087+ Applicability :: MachineApplicable ,
2088+ ) ;
2089+ } else {
2090+ err. help ( fluent:: parse_maybe_missing_macro_rules_name) ;
2091+ }
2092+
2093+ return Err ( err) ;
2094+ }
2095+ } ;
2096+
2097+ if ident. name == sym:: macro_rules {
2098+ self . sess . emit_err ( errors:: MacroRulesNamedMacroRules { span : ident. span } ) ;
2099+ }
20702100
20712101 if self . eat ( & token:: Not ) {
20722102 // Handle macro_rules! foo!
0 commit comments