11pub use BinOpToken :: * ;
22pub use LitKind :: * ;
3- pub use Nonterminal :: * ;
43pub use TokenKind :: * ;
54
65use crate :: ast;
76use crate :: util:: case:: Case ;
87
9- use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
10- use rustc_data_structures:: sync:: Lrc ;
118use rustc_macros:: HashStable_Generic ;
129use rustc_span:: symbol:: { kw, sym} ;
1310#[ allow( hidden_glob_reexports) ]
@@ -262,9 +259,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
262259 . contains ( & name)
263260}
264261
265- // SAFETY: due to the `Clone` impl below, all fields of all variants other than
266- // `Interpolated` must impl `Copy`.
267- #[ derive( PartialEq , Encodable , Decodable , Debug , HashStable_Generic ) ]
262+ #[ derive( Clone , PartialEq , Encodable , Decodable , Debug , HashStable_Generic ) ]
268263pub enum TokenKind {
269264 /* Expression-operator symbols. */
270265 Eq ,
@@ -308,26 +303,23 @@ pub enum TokenKind {
308303 Literal ( Lit ) ,
309304
310305 /// Identifier token.
311- /// Do not forget about `NtIdent ` when you want to match on identifiers.
306+ /// Do not forget about `InterpolatedIdent ` when you want to match on identifiers.
312307 /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
313308 /// treat regular and interpolated identifiers in the same way.
314309 Ident ( Symbol , /* is_raw */ bool ) ,
310+ /// This `Span` is the span of the original identifier passed to the
311+ /// declarative macro. The span in the `Token` is the span of the `ident`
312+ /// metavariable in the macro's RHS.
313+ InterpolatedIdent ( Symbol , /* is_raw */ bool , Span ) ,
315314 /// Lifetime identifier token.
316- /// Do not forget about `NtLifetime ` when you want to match on lifetime identifiers.
315+ /// Do not forget about `InterpolatedLIfetime ` when you want to match on lifetime identifiers.
317316 /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
318317 /// treat regular and interpolated lifetime identifiers in the same way.
319318 Lifetime ( Symbol ) ,
320-
321- /// An embedded AST node, as produced by a macro. This only exists for
322- /// historical reasons. We'd like to get rid of it, for multiple reasons.
323- /// - It's conceptually very strange. Saying a token can contain an AST
324- /// node is like saying, in natural language, that a word can contain a
325- /// sentence.
326- /// - It requires special handling in a bunch of places in the parser.
327- /// - It prevents `Token` from implementing `Copy`.
328- /// It adds complexity and likely slows things down. Please don't add new
329- /// occurrences of this token kind!
330- Interpolated ( Lrc < Nonterminal > ) ,
319+ /// This `Span` is the span of the original lifetime passed to the
320+ /// declarative macro. The span in the `Token` is the span of the
321+ /// `lifetime` metavariable in the macro's RHS.
322+ InterpolatedLifetime ( Symbol , Span ) ,
331323
332324 /// A doc comment token.
333325 /// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc)
@@ -337,19 +329,6 @@ pub enum TokenKind {
337329 Eof ,
338330}
339331
340- impl Clone for TokenKind {
341- fn clone ( & self ) -> Self {
342- // `TokenKind` would impl `Copy` if it weren't for `Interpolated`. So
343- // for all other variants, this implementation of `clone` is just like
344- // a copy. This is faster than the `derive(Clone)` version which has a
345- // separate path for every variant.
346- match self {
347- Interpolated ( nt) => Interpolated ( nt. clone ( ) ) ,
348- _ => unsafe { std:: ptr:: read ( self ) } ,
349- }
350- }
351- }
352-
353332#[ derive( Clone , PartialEq , Encodable , Decodable , Debug , HashStable_Generic ) ]
354333pub struct Token {
355334 pub kind : TokenKind ,
@@ -433,8 +412,12 @@ impl Token {
433412 /// Note that keywords are also identifiers, so they should use this
434413 /// if they keep spans or perform edition checks.
435414 pub fn uninterpolated_span ( & self ) -> Span {
436- match & self . kind {
437- Interpolated ( nt) => nt. span ( ) ,
415+ match self . kind {
416+ InterpolatedIdent ( _, _, uninterpolated_span)
417+ | InterpolatedLifetime ( _, uninterpolated_span) => uninterpolated_span,
418+ OpenDelim ( Delimiter :: Invisible ( InvisibleSource :: MetaVar ( kind) ) ) => {
419+ panic ! ( "njn: uninterpolated_span {kind:?}" ) ;
420+ }
438421 _ => self . span ,
439422 }
440423 }
@@ -449,8 +432,15 @@ impl Token {
449432 | BinOpEq ( _) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon
450433 | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true ,
451434
452- OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | DocComment ( ..) | Ident ( ..)
453- | Lifetime ( ..) | Interpolated ( ..) | Eof => false ,
435+ OpenDelim ( ..)
436+ | CloseDelim ( ..)
437+ | Literal ( ..)
438+ | DocComment ( ..)
439+ | Ident ( ..)
440+ | InterpolatedIdent ( ..)
441+ | Lifetime ( ..)
442+ | InterpolatedLifetime ( ..)
443+ | Eof => false ,
454444 }
455445 }
456446
@@ -612,13 +602,13 @@ impl Token {
612602 /// into the regular identifier or lifetime token it refers to,
613603 /// otherwise returns the original token.
614604 pub fn uninterpolate ( & self ) -> Cow < ' _ , Token > {
615- match & self . kind {
616- Interpolated ( nt ) => match * * nt {
617- NtIdent ( ident , is_raw) => {
618- Cow :: Owned ( Token :: new ( Ident ( ident . name , is_raw ) , ident . span ) )
619- }
620- NtLifetime ( ident ) => Cow :: Owned ( Token :: new ( Lifetime ( ident . name ) , ident . span ) ) ,
621- } ,
605+ match self . kind {
606+ InterpolatedIdent ( name , is_raw , uninterpolated_span ) => {
607+ Cow :: Owned ( Token :: new ( Ident ( name , is_raw) , uninterpolated_span ) )
608+ }
609+ InterpolatedLifetime ( name , uninterpolated_span ) => {
610+ Cow :: Owned ( Token :: new ( Lifetime ( name) , uninterpolated_span ) )
611+ }
622612 _ => Cow :: Borrowed ( self ) ,
623613 }
624614 }
@@ -627,12 +617,11 @@ impl Token {
627617 #[ inline]
628618 pub fn ident ( & self ) -> Option < ( Ident , /* is_raw */ bool ) > {
629619 // We avoid using `Token::uninterpolate` here because it's slow.
630- match & self . kind {
631- & Ident ( name, is_raw) => Some ( ( Ident :: new ( name, self . span ) , is_raw) ) ,
632- Interpolated ( nt) => match * * nt {
633- NtIdent ( ident, is_raw) => Some ( ( ident, is_raw) ) ,
634- _ => None ,
635- } ,
620+ match self . kind {
621+ Ident ( name, is_raw) => Some ( ( Ident :: new ( name, self . span ) , is_raw) ) ,
622+ InterpolatedIdent ( name, is_raw, uninterpolated_span) => {
623+ Some ( ( Ident :: new ( name, uninterpolated_span) , is_raw) )
624+ }
636625 _ => None ,
637626 }
638627 }
@@ -641,12 +630,11 @@ impl Token {
641630 #[ inline]
642631 pub fn lifetime ( & self ) -> Option < Ident > {
643632 // We avoid using `Token::uninterpolate` here because it's slow.
644- match & self . kind {
645- & Lifetime ( name) => Some ( Ident :: new ( name, self . span ) ) ,
646- Interpolated ( nt) => match * * nt {
647- NtLifetime ( ident) => Some ( ident) ,
648- _ => None ,
649- } ,
633+ match self . kind {
634+ Lifetime ( name) => Some ( Ident :: new ( name, self . span ) ) ,
635+ InterpolatedLifetime ( name, uninterpolated_span) => {
636+ Some ( Ident :: new ( name, uninterpolated_span) )
637+ }
650638 _ => None ,
651639 }
652640 }
@@ -822,10 +810,35 @@ impl Token {
822810 _ => return None ,
823811 } ,
824812
825- Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq ( ..) | At | DotDotDot
826- | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
827- | Question | OpenDelim ( ..) | CloseDelim ( ..) | Literal ( ..) | Ident ( ..)
828- | Lifetime ( ..) | Interpolated ( ..) | DocComment ( ..) | Eof => return None ,
813+ Le
814+ | EqEq
815+ | Ne
816+ | Ge
817+ | AndAnd
818+ | OrOr
819+ | Tilde
820+ | BinOpEq ( ..)
821+ | At
822+ | DotDotDot
823+ | DotDotEq
824+ | Comma
825+ | Semi
826+ | ModSep
827+ | RArrow
828+ | LArrow
829+ | FatArrow
830+ | Pound
831+ | Dollar
832+ | Question
833+ | OpenDelim ( ..)
834+ | CloseDelim ( ..)
835+ | Literal ( ..)
836+ | Ident ( ..)
837+ | InterpolatedIdent ( ..)
838+ | Lifetime ( ..)
839+ | InterpolatedLifetime ( ..)
840+ | DocComment ( ..)
841+ | Eof => return None ,
829842 } ;
830843
831844 Some ( Token :: new ( kind, self . span . to ( joint. span ) ) )
@@ -839,13 +852,8 @@ impl PartialEq<TokenKind> for Token {
839852 }
840853}
841854
842- #[ derive( Clone , Encodable , Decodable ) ]
843- /// For interpolation during macro expansion.
844- pub enum Nonterminal {
845- NtIdent ( Ident , /* is_raw */ bool ) ,
846- NtLifetime ( Ident ) ,
847- }
848-
855+ // njn: introduce cut-back version lacking Ident/Lifetime?
856+ // - could that simplify the Pat cases too?
849857#[ derive( Debug , Copy , Clone , PartialEq , Eq , Encodable , Decodable , Hash , HashStable_Generic ) ]
850858pub enum NonterminalKind {
851859 Item ,
@@ -859,6 +867,7 @@ pub enum NonterminalKind {
859867 PatWithOr ,
860868 Expr ,
861869 Ty ,
870+ //njn: explain how these are never put in Invisible delims
862871 Ident ,
863872 Lifetime ,
864873 Literal ,
@@ -924,48 +933,6 @@ impl fmt::Display for NonterminalKind {
924933 }
925934}
926935
927- impl Nonterminal {
928- pub fn span ( & self ) -> Span {
929- match self {
930- NtIdent ( ident, _) | NtLifetime ( ident) => ident. span ,
931- }
932- }
933- }
934-
935- impl PartialEq for Nonterminal {
936- fn eq ( & self , rhs : & Self ) -> bool {
937- match ( self , rhs) {
938- ( NtIdent ( ident_lhs, is_raw_lhs) , NtIdent ( ident_rhs, is_raw_rhs) ) => {
939- ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs
940- }
941- ( NtLifetime ( ident_lhs) , NtLifetime ( ident_rhs) ) => ident_lhs == ident_rhs,
942- // FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them
943- // correctly based on data from AST. This will prevent them from matching each other
944- // in macros. The comparison will become possible only when each nonterminal has an
945- // attached token stream from which it was parsed.
946- _ => false ,
947- }
948- }
949- }
950-
951- impl fmt:: Debug for Nonterminal {
952- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
953- match * self {
954- NtIdent ( ..) => f. pad ( "NtIdent(..)" ) ,
955- NtLifetime ( ..) => f. pad ( "NtLifetime(..)" ) ,
956- }
957- }
958- }
959-
960- impl < CTX > HashStable < CTX > for Nonterminal
961- where
962- CTX : crate :: HashStableContext ,
963- {
964- fn hash_stable ( & self , _hcx : & mut CTX , _hasher : & mut StableHasher ) {
965- panic ! ( "interpolated tokens should not be present in the HIR" )
966- }
967- }
968-
969936// Some types are used a lot. Make sure they don't unintentionally get bigger.
970937#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
971938mod size_asserts {
@@ -974,7 +941,6 @@ mod size_asserts {
974941 // tidy-alphabetical-start
975942 static_assert_size ! ( Lit , 12 ) ;
976943 static_assert_size ! ( LitKind , 2 ) ;
977- static_assert_size ! ( Nonterminal , 16 ) ;
978944 static_assert_size ! ( Token , 24 ) ;
979945 static_assert_size ! ( TokenKind , 16 ) ;
980946 // tidy-alphabetical-end
0 commit comments