@@ -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,42 @@ 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+ match (
2077+ & self . token . kind ,
2078+ self . look_ahead ( 1 , |token| token. ident ( ) ) ,
2079+ self . look_ahead ( 2 , |token| {
2080+ ( token. kind == TokenKind :: CloseDelim ( Delimiter :: Parenthesis ) )
2081+ . then_some ( token. span )
2082+ } ) ,
2083+ ) {
2084+ (
2085+ TokenKind :: OpenDelim ( Delimiter :: Parenthesis ) ,
2086+ Some ( ( Ident { name, .. } , _) ) ,
2087+ Some ( closing_span) ,
2088+ ) => {
2089+ err. span_suggestion (
2090+ self . token . span . with_hi ( closing_span. hi ( ) ) ,
2091+ "try removing the parenthesis around the name for this `macro_rules!`" ,
2092+ name,
2093+ Applicability :: MachineApplicable ,
2094+ ) ;
2095+ }
2096+ _ => {
2097+ err. help ( fluent:: parse_maybe_missing_macro_rules_name) ;
2098+ }
2099+ }
2100+
2101+ return Err ( err) ;
2102+ }
2103+ } ;
2104+
2105+ if ident. name == sym:: macro_rules {
2106+ self . sess . emit_err ( errors:: MacroRulesNamedMacroRules { span : ident. span } ) ;
2107+ }
20702108
20712109 if self . eat ( & token:: Not ) {
20722110 // Handle macro_rules! foo!
0 commit comments