@@ -86,7 +86,7 @@ use self::TokenTreeOrTokenTreeVec::*;
8686
8787use ast:: Ident ;
8888use syntax_pos:: { self , BytePos , Span } ;
89- use codemap:: Spanned ;
89+ use codemap:: respan ;
9090use errors:: FatalError ;
9191use ext:: tt:: quoted:: { self , TokenTree } ;
9292use parse:: { Directory , ParseSess } ;
@@ -709,6 +709,15 @@ pub fn parse(
709709 }
710710}
711711
712+ /// The token is an identifier, but not `_`.
713+ /// We prohibit passing `_` to macros expecting `ident` for now.
714+ fn get_macro_ident ( token : & Token ) -> Option < Ident > {
715+ match * token {
716+ token:: Ident ( ident) if ident. name != keywords:: Underscore . name ( ) => Some ( ident) ,
717+ _ => None ,
718+ }
719+ }
720+
712721/// Checks whether a non-terminal may begin with a particular token.
713722///
714723/// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
@@ -725,7 +734,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
725734 match name {
726735 "expr" => token. can_begin_expr ( ) ,
727736 "ty" => token. can_begin_type ( ) ,
728- "ident" => token. is_ident ( ) ,
737+ "ident" => get_macro_ident ( token) . is_some ( ) ,
729738 "vis" => match * token {
730739 // The follow-set of :vis + "priv" keyword + interpolated
731740 Token :: Comma | Token :: Ident ( _) | Token :: Interpolated ( _) => true ,
@@ -814,21 +823,14 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
814823 "expr" => token:: NtExpr ( panictry ! ( p. parse_expr( ) ) ) ,
815824 "ty" => token:: NtTy ( panictry ! ( p. parse_ty( ) ) ) ,
816825 // this could be handled like a token, since it is one
817- "ident" => match p. token {
818- token:: Ident ( sn) => {
819- p. bump ( ) ;
820- token:: NtIdent ( Spanned :: < Ident > {
821- node : sn,
822- span : p. prev_span ,
823- } )
824- }
825- _ => {
826- let token_str = pprust:: token_to_string ( & p. token ) ;
827- p. fatal ( & format ! ( "expected ident, found {}" , & token_str[ ..] ) )
828- . emit ( ) ;
829- FatalError . raise ( )
830- }
831- } ,
826+ "ident" => if let Some ( ident) = get_macro_ident ( & p. token ) {
827+ p. bump ( ) ;
828+ token:: NtIdent ( respan ( p. prev_span , ident) )
829+ } else {
830+ let token_str = pprust:: token_to_string ( & p. token ) ;
831+ p. fatal ( & format ! ( "expected ident, found {}" , & token_str) ) . emit ( ) ;
832+ FatalError . raise ( )
833+ }
832834 "path" => token:: NtPath ( panictry ! ( p. parse_path_common( PathStyle :: Type , false ) ) ) ,
833835 "meta" => token:: NtMeta ( panictry ! ( p. parse_meta_item( ) ) ) ,
834836 "vis" => token:: NtVis ( panictry ! ( p. parse_visibility( true ) ) ) ,
0 commit comments