@@ -111,7 +111,7 @@ impl Lit {
111111 Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) => Some ( Lit :: new ( Bool , name, None ) ) ,
112112 Literal ( token_lit) => Some ( token_lit) ,
113113 Interpolated ( 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 {
117117 Some ( 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.
320320 Ident ( 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.
325330 Lifetime ( 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.
442455 pub 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
461475 OpenDelim ( ..) | 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 {
486500 PathSep | // global path
487501 Lifetime ( ..) | // labeled loop
488502 Pound => true , // expression attributes
489- Interpolated ( ref nt) => matches ! ( & nt . 0 , NtLiteral ( ..) |
503+ Interpolated ( ref nt) => matches ! ( & * * nt , NtLiteral ( ..) |
490504 NtExpr ( ..) |
491505 NtBlock ( ..) |
492506 NtPath ( ..) ) ,
@@ -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 ( ..) |
514528 NtPat ( ..) |
515529 NtBlock ( ..) |
516530 NtPath ( ..) ) ,
@@ -533,7 +547,7 @@ impl Token {
533547 Lifetime ( ..) | // lifetime bound in trait object
534548 Lt | BinOp ( Shl ) | // associated path
535549 PathSep => 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 {
544558 pub fn can_begin_const_arg ( & self ) -> bool {
545559 match self . kind {
546560 OpenDelim ( 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 {
589603 match self . uninterpolate ( ) . kind {
590604 Literal ( ..) | BinOp ( Minus ) => true ,
591605 Ident ( name, IdentIsRaw :: No ) if name. is_bool_lit ( ) => true ,
592- Interpolated ( ref nt) => match & nt . 0 {
606+ Interpolated ( ref nt) => match & * * nt {
593607 NtLiteral ( _) => true ,
594608 NtExpr ( 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.
611625 pub 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]
626635 pub 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]
640646 pub 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.
669672 fn is_whole_path ( & self ) -> bool {
670673 if let Interpolated ( nt) = & self . kind
671- && let NtPath ( ..) = & nt . 0
674+ && let NtPath ( ..) = & * * nt
672675 {
673676 return true ;
674677 }
@@ -681,7 +684,7 @@ impl Token {
681684 /// (which happens while parsing the result of macro expansion)?
682685 pub fn is_whole_expr ( & self ) -> bool {
683686 if let Interpolated ( nt) = & self . kind
684- && let NtExpr ( _) | NtLiteral ( _) | NtPath ( _) | NtBlock ( _) = & nt . 0
687+ && let NtExpr ( _) | NtLiteral ( _) | NtPath ( _) | NtBlock ( _) = & * * nt
685688 {
686689 return true ;
687690 }
@@ -692,7 +695,7 @@ impl Token {
692695 /// Is the token an interpolated block (`$b:block`)?
693696 pub fn is_whole_block ( & self ) -> bool {
694697 if let Interpolated ( nt) = & self . kind
695- && let NtBlock ( ..) = & nt . 0
698+ && let NtBlock ( ..) = & * * nt
696699 {
697700 return true ;
698701 }
@@ -833,8 +836,10 @@ impl Token {
833836
834837 Le | 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
840845 Some ( Token :: new ( kind, self . span . to ( joint. span ) ) )
@@ -857,8 +862,6 @@ pub enum Nonterminal {
857862 NtPat ( P < ast:: Pat > ) ,
858863 NtExpr ( P < ast:: Expr > ) ,
859864 NtTy ( P < ast:: Ty > ) ,
860- NtIdent ( Ident , IdentIsRaw ) ,
861- NtLifetime ( Ident ) ,
862865 NtLiteral ( P < ast:: Expr > ) ,
863866 /// Stuff inside brackets for attributes
864867 NtMeta ( P < ast:: AttrItem > ) ,
@@ -953,7 +956,6 @@ impl Nonterminal {
953956 NtPat ( pat) => pat. span ,
954957 NtExpr ( expr) | NtLiteral ( expr) => expr. span ,
955958 NtTy ( ty) => ty. span ,
956- NtIdent ( ident, _) | NtLifetime ( ident) => ident. span ,
957959 NtMeta ( attr_item) => attr_item. span ( ) ,
958960 NtPath ( path) => path. span ,
959961 NtVis ( vis) => vis. span ,
@@ -969,8 +971,6 @@ impl Nonterminal {
969971 NtExpr ( ..) => "expression" ,
970972 NtLiteral ( ..) => "literal" ,
971973 NtTy ( ..) => "type" ,
972- NtIdent ( ..) => "identifier" ,
973- NtLifetime ( ..) => "lifetime" ,
974974 NtMeta ( ..) => "attribute" ,
975975 NtPath ( ..) => "path" ,
976976 NtVis ( ..) => "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 {
1003997 NtPat ( ..) => f. pad ( "NtPat(..)" ) ,
1004998 NtExpr ( ..) => f. pad ( "NtExpr(..)" ) ,
1005999 NtTy ( ..) => f. pad ( "NtTy(..)" ) ,
1006- NtIdent ( ..) => f. pad ( "NtIdent(..)" ) ,
10071000 NtLiteral ( ..) => f. pad ( "NtLiteral(..)" ) ,
10081001 NtMeta ( ..) => f. pad ( "NtMeta(..)" ) ,
10091002 NtPath ( ..) => f. pad ( "NtPath(..)" ) ,
10101003 NtVis ( ..) => f. pad ( "NtVis(..)" ) ,
1011- NtLifetime ( ..) => f. pad ( "NtLifetime(..)" ) ,
10121004 }
10131005 }
10141006}
0 commit comments