@@ -111,7 +111,7 @@ impl Lit {
111111Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) =>Some ( Lit :: new ( Bool , name, None ) ) ,
112112Literal ( token_lit) =>Some ( token_lit) ,
113113Interpolated ( ref nt)
114- if let NtExpr ( expr) |NtLiteral ( expr) =& nt . 0
114+ if let NtExpr ( expr) |NtLiteral ( expr) =& * * nt
115115 &&let ast:: ExprKind :: Lit ( token_lit) = expr. kind =>
116116{
117117Some ( token_lit)
@@ -318,11 +318,20 @@ pub enum TokenKind {
318318/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
319319/// treat regular and interpolated identifiers in the same way.
320320Ident ( Symbol , IdentIsRaw ) ,
321+ /// This identifier (and its span) is the identifier passed to the
322+ /// declarative macro. The span in the surrounding `Token` is the span of
323+ /// the `ident` metavariable in the macro's RHS.
324+ NtIdent ( Ident , IdentIsRaw ) ,
325+
321326/// Lifetime identifier token.
322327/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
323328/// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
324329/// treat regular and interpolated lifetime identifiers in the same way.
325330Lifetime ( Symbol ) ,
331+ /// This identifier (and its span) is the lifetime passed to the
332+ /// declarative macro. The span in the surrounding `Token` is the span of
333+ /// the `lifetime` metavariable in the macro's RHS.
334+ NtLifetime ( Ident ) ,
326335
327336/// An embedded AST node, as produced by a macro. This only exists for
328337/// historical reasons. We'd like to get rid of it, for multiple reasons.
@@ -333,7 +342,11 @@ pub enum TokenKind {
333342/// - It prevents `Token` from implementing `Copy`.
334343/// It adds complexity and likely slows things down. Please don't add new
335344/// occurrences of this token kind!
336- Interpolated ( Lrc < ( Nonterminal , Span ) > ) ,
345+ ///
346+ /// The span in the surrounding `Token` is that of the metavariable in the
347+ /// macro's RHS. The span within the Nonterminal is that of the fragment
348+ /// passed to the macro at the call site.
349+ Interpolated ( Lrc < Nonterminal > ) ,
337350
338351/// A doc comment token.
339352/// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc)
@@ -440,8 +453,9 @@ impl Token {
440453/// Note that keywords are also identifiers, so they should use this
441454/// if they keep spans or perform edition checks.
442455pub fn uninterpolated_span ( & self ) ->Span {
443- match & self . kind {
444- Interpolated ( nt) => nt. 0 . use_span ( ) ,
456+ match self . kind {
457+ NtIdent ( ident, _) |NtLifetime ( ident) => ident. span ,
458+ Interpolated ( ref nt) => nt. use_span ( ) ,
445459 _ =>self . span ,
446460}
447461}
@@ -459,7 +473,7 @@ impl Token {
459473}
460474
461475OpenDelim ( ..) |CloseDelim ( ..) |Literal ( ..) |DocComment ( ..) |Ident ( ..)
462- |Lifetime ( ..) |Interpolated ( ..) |Eof =>false ,
476+ |NtIdent ( .. ) | Lifetime ( .. ) | NtLifetime ( ..) |Interpolated ( ..) |Eof =>false ,
463477}
464478}
465479
@@ -486,7 +500,7 @@ impl Token {
486500PathSep |// global path
487501Lifetime ( ..) |// labeled loop
488502Pound =>true , // expression attributes
489- Interpolated ( ref nt) =>matches ! ( & nt . 0 , NtLiteral ( ..) |
503+ Interpolated ( ref nt) =>matches ! ( & * * nt , NtLiteral ( ..) |
490504NtExpr ( ..) |
491505NtBlock ( ..) |
492506NtPath ( ..) ) ,
@@ -510,7 +524,7 @@ impl Token {
510524 |DotDot |DotDotDot |DotDotEq // ranges
511525 |Lt |BinOp ( Shl ) // associated path
512526 |PathSep =>true , // global path
513- Interpolated ( ref nt) =>matches ! ( & nt . 0 , NtLiteral ( ..) |
527+ Interpolated ( ref nt) =>matches ! ( & * * nt , NtLiteral ( ..) |
514528NtPat ( ..) |
515529NtBlock ( ..) |
516530NtPath ( ..) ) ,
@@ -533,7 +547,7 @@ impl Token {
533547Lifetime ( ..) |// lifetime bound in trait object
534548Lt |BinOp ( Shl ) |// associated path
535549PathSep =>true , // global path
536- Interpolated ( ref nt) =>matches ! ( & nt . 0 , NtTy ( ..) |NtPath ( ..) ) ,
550+ Interpolated ( ref nt) =>matches ! ( & * * nt , NtTy ( ..) |NtPath ( ..) ) ,
537551// For anonymous structs or unions, which only appear in specific positions
538552// (type of struct fields or union fields), we don't consider them as regular types
539553 _ =>false ,
@@ -544,7 +558,7 @@ impl Token {
544558pub fn can_begin_const_arg ( & self ) ->bool {
545559match self . kind {
546560OpenDelim ( Delimiter :: Brace ) =>true ,
547- Interpolated ( ref nt) =>matches ! ( & nt . 0 , NtExpr ( ..) |NtBlock ( ..) |NtLiteral ( ..) ) ,
561+ Interpolated ( ref nt) =>matches ! ( & * * nt , NtExpr ( ..) |NtBlock ( ..) |NtLiteral ( ..) ) ,
548562 _ =>self . can_begin_literal_maybe_minus ( ) ,
549563}
550564}
@@ -589,7 +603,7 @@ impl Token {
589603match self . uninterpolate ( ) . kind {
590604Literal ( ..) |BinOp ( Minus ) =>true ,
591605Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) =>true ,
592- Interpolated ( ref nt) =>match & nt . 0 {
606+ Interpolated ( ref nt) =>match & * * nt {
593607NtLiteral ( _) =>true ,
594608NtExpr ( e) =>match & e. kind {
595609 ast:: ExprKind :: Lit ( _) =>true ,
@@ -609,14 +623,9 @@ impl Token {
609623/// into the regular identifier or lifetime token it refers to,
610624/// otherwise returns the original token.
611625pub fn uninterpolate ( & self ) ->Cow < ' _ , Token > {
612- match & self . kind {
613- Interpolated ( nt) =>match & nt. 0 {
614- NtIdent ( ident, is_raw) =>{
615- Cow :: Owned ( Token :: new ( Ident ( ident. name , * is_raw) , ident. span ) )
616- }
617- NtLifetime ( ident) =>Cow :: Owned ( Token :: new ( Lifetime ( ident. name ) , ident. span ) ) ,
618- _ =>Cow :: Borrowed ( self ) ,
619- } ,
626+ match self . kind {
627+ NtIdent ( ident, is_raw) =>Cow :: Owned ( Token :: new ( Ident ( ident. name , is_raw) , ident. span ) ) ,
628+ NtLifetime ( ident) =>Cow :: Owned ( Token :: new ( Lifetime ( ident. name ) , ident. span ) ) ,
620629 _ =>Cow :: Borrowed ( self ) ,
621630}
622631}
@@ -625,12 +634,9 @@ impl Token {
625634#[ inline]
626635pub fn ident ( & self ) ->Option < ( Ident , IdentIsRaw ) > {
627636// We avoid using `Token::uninterpolate` here because it's slow.
628- match & self . kind {
629- & Ident ( name, is_raw) =>Some ( ( Ident :: new ( name, self . span ) , is_raw) ) ,
630- Interpolated ( nt) =>match & nt. 0 {
631- NtIdent ( ident, is_raw) =>Some ( ( * ident, * is_raw) ) ,
632- _ =>None ,
633- } ,
637+ match self . kind {
638+ Ident ( name, is_raw) =>Some ( ( Ident :: new ( name, self . span ) , is_raw) ) ,
639+ NtIdent ( ident, is_raw) =>Some ( ( ident, is_raw) ) ,
634640 _ =>None ,
635641}
636642}
@@ -639,12 +645,9 @@ impl Token {
639645#[ inline]
640646pub fn lifetime ( & self ) ->Option < Ident > {
641647// We avoid using `Token::uninterpolate` here because it's slow.
642- match & self . kind {
643- & Lifetime ( name) =>Some ( Ident :: new ( name, self . span ) ) ,
644- Interpolated ( nt) =>match & nt. 0 {
645- NtLifetime ( ident) =>Some ( * ident) ,
646- _ =>None ,
647- } ,
648+ match self . kind {
649+ Lifetime ( name) =>Some ( Ident :: new ( name, self . span ) ) ,
650+ NtLifetime ( ident) =>Some ( ident) ,
648651 _ =>None ,
649652}
650653}
@@ -668,7 +671,7 @@ impl Token {
668671/// Returns `true` if the token is an interpolated path.
669672fn is_whole_path ( & self ) ->bool {
670673if let Interpolated ( nt) =& self . kind
671- &&let NtPath ( ..) =& nt . 0
674+ &&let NtPath ( ..) =& * * nt
672675{
673676return true ;
674677}
@@ -681,7 +684,7 @@ impl Token {
681684/// (which happens while parsing the result of macro expansion)?
682685pub fn is_whole_expr ( & self ) ->bool {
683686if let Interpolated ( nt) =& self . kind
684- &&let NtExpr ( _) |NtLiteral ( _) |NtPath ( _) |NtBlock ( _) =& nt . 0
687+ &&let NtExpr ( _) |NtLiteral ( _) |NtPath ( _) |NtBlock ( _) =& * * nt
685688{
686689return true ;
687690}
@@ -692,7 +695,7 @@ impl Token {
692695/// Is the token an interpolated block (`$b:block`)?
693696pub fn is_whole_block ( & self ) ->bool {
694697if let Interpolated ( nt) =& self . kind
695- &&let NtBlock ( ..) =& nt . 0
698+ &&let NtBlock ( ..) =& * * nt
696699{
697700return true ;
698701}
@@ -833,8 +836,10 @@ impl Token {
833836
834837Le |EqEq |Ne |Ge |AndAnd |OrOr |Tilde |BinOpEq ( ..) |At |DotDotDot
835838 |DotDotEq |Comma |Semi |PathSep |RArrow |LArrow |FatArrow |Pound |Dollar
836- |Question |OpenDelim ( ..) |CloseDelim ( ..) |Literal ( ..) |Ident ( ..)
837- |Lifetime ( ..) |Interpolated ( ..) |DocComment ( ..) |Eof =>return None ,
839+ |Question |OpenDelim ( ..) |CloseDelim ( ..) |Literal ( ..) |Ident ( ..) |NtIdent ( ..)
840+ |Lifetime ( ..) |NtLifetime ( ..) |Interpolated ( ..) |DocComment ( ..) |Eof =>{
841+ return None ;
842+ }
838843} ;
839844
840845Some ( Token :: new ( kind, self . span . to ( joint. span ) ) )
@@ -857,8 +862,6 @@ pub enum Nonterminal {
857862NtPat ( P < ast:: Pat > ) ,
858863NtExpr ( P < ast:: Expr > ) ,
859864NtTy ( P < ast:: Ty > ) ,
860- NtIdent ( Ident , IdentIsRaw ) ,
861- NtLifetime ( Ident ) ,
862865NtLiteral ( P < ast:: Expr > ) ,
863866/// Stuff inside brackets for attributes
864867NtMeta ( P < ast:: AttrItem > ) ,
@@ -953,7 +956,6 @@ impl Nonterminal {
953956NtPat ( pat) => pat. span ,
954957NtExpr ( expr) |NtLiteral ( expr) => expr. span ,
955958NtTy ( ty) => ty. span ,
956- NtIdent ( ident, _) |NtLifetime ( ident) => ident. span ,
957959NtMeta ( attr_item) => attr_item. span ( ) ,
958960NtPath ( path) => path. span ,
959961NtVis ( vis) => vis. span ,
@@ -969,8 +971,6 @@ impl Nonterminal {
969971NtExpr ( ..) =>"expression" ,
970972NtLiteral ( ..) =>"literal" ,
971973NtTy ( ..) =>"type" ,
972- NtIdent ( ..) =>"identifier" ,
973- NtLifetime ( ..) =>"lifetime" ,
974974NtMeta ( ..) =>"attribute" ,
975975NtPath ( ..) =>"path" ,
976976NtVis ( ..) =>"visibility" ,
@@ -979,18 +979,12 @@ impl Nonterminal {
979979}
980980
981981impl PartialEq for Nonterminal {
982- fn eq ( & self , rhs : & Self ) ->bool {
983- match ( self , rhs) {
984- ( NtIdent ( ident_lhs, is_raw_lhs) , NtIdent ( ident_rhs, is_raw_rhs) ) =>{
985- ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs
986- }
987- ( NtLifetime ( ident_lhs) , NtLifetime ( ident_rhs) ) => ident_lhs == ident_rhs,
988- // FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them
989- // correctly based on data from AST. This will prevent them from matching each other
990- // in macros. The comparison will become possible only when each nonterminal has an
991- // attached token stream from which it was parsed.
992- _ =>false ,
993- }
982+ fn eq ( & self , _rhs : & Self ) ->bool {
983+ // FIXME: Assume that all nonterminals are not equal, we can't compare them
984+ // correctly based on data from AST. This will prevent them from matching each other
985+ // in macros. The comparison will become possible only when each nonterminal has an
986+ // attached token stream from which it was parsed.
987+ false
994988}
995989}
996990
@@ -1003,12 +997,10 @@ impl fmt::Debug for Nonterminal {
1003997NtPat ( ..) => f. pad ( "NtPat(..)" ) ,
1004998NtExpr ( ..) => f. pad ( "NtExpr(..)" ) ,
1005999NtTy ( ..) => f. pad ( "NtTy(..)" ) ,
1006- NtIdent ( ..) => f. pad ( "NtIdent(..)" ) ,
10071000NtLiteral ( ..) => f. pad ( "NtLiteral(..)" ) ,
10081001NtMeta ( ..) => f. pad ( "NtMeta(..)" ) ,
10091002NtPath ( ..) => f. pad ( "NtPath(..)" ) ,
10101003NtVis ( ..) => f. pad ( "NtVis(..)" ) ,
1011- NtLifetime ( ..) => f. pad ( "NtLifetime(..)" ) ,
10121004}
10131005}
10141006}