@@ -17,23 +17,48 @@ use rustc_data_structures::sync::Lrc;
1717use rustc_span:: symbol:: Ident ;
1818use rustc_span:: Span ;
1919
20- /// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
21- /// that the delimiter itself might be `NoDelim`.
20+ /// Contains the sub-token-trees of a "delimited" token tree such as `(a b c)`. The delimiter itself
21+ /// might be `NoDelim`.
2222#[ derive( Clone , PartialEq , Encodable , Decodable , Debug ) ]
2323struct Delimited {
2424 delim : token:: DelimToken ,
25- tts : Vec < TokenTree > ,
25+ /// Note: This contains the opening and closing delimiters tokens (e.g. `(` and `)`). Note that
26+ /// these could be `NoDelim`. These token kinds must match `delim`, and the methods below
27+ /// debug_assert this.
28+ all_tts : Vec < TokenTree > ,
2629}
2730
2831impl Delimited {
29- /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter.
30- fn open_tt ( & self , span : DelimSpan ) -> TokenTree {
31- TokenTree :: token ( token:: OpenDelim ( self . delim ) , span. open )
32+ /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter. Panics if
33+ /// the delimiter is `NoDelim`.
34+ fn open_tt ( & self ) -> & TokenTree {
35+ let tt = self . all_tts . first ( ) . unwrap ( ) ;
36+ debug_assert ! ( matches!(
37+ tt,
38+ & TokenTree :: Token ( token:: Token { kind: token:: OpenDelim ( d) , .. } ) if d == self . delim
39+ ) ) ;
40+ tt
41+ }
42+
43+ /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter. Panics if
44+ /// the delimeter is `NoDelim`.
45+ fn close_tt ( & self ) -> & TokenTree {
46+ let tt = self . all_tts . last ( ) . unwrap ( ) ;
47+ debug_assert ! ( matches!(
48+ tt,
49+ & TokenTree :: Token ( token:: Token { kind: token:: CloseDelim ( d) , .. } ) if d == self . delim
50+ ) ) ;
51+ tt
3252 }
3353
34- /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter.
35- fn close_tt ( & self , span : DelimSpan ) -> TokenTree {
36- TokenTree :: token ( token:: CloseDelim ( self . delim ) , span. close )
54+ /// Returns the tts excluding the outer delimiters.
55+ ///
56+ /// FIXME: #67062 has details about why this is sub-optimal.
57+ fn inner_tts ( & self ) -> & [ TokenTree ] {
58+ // These functions are called for the assertions within them.
59+ let _open_tt = self . open_tt ( ) ;
60+ let _close_tt = self . close_tt ( ) ;
61+ & self . all_tts [ 1 ..self . all_tts . len ( ) - 1 ]
3762 }
3863}
3964
@@ -73,35 +98,24 @@ enum KleeneOp {
7398 ZeroOrOne ,
7499}
75100
76- /// Similar to `tokenstream::TokenTree`, except that `$i `, `$i:ident `, `$(...)`,
77- /// and `${...} ` are "first-class" token trees. Useful for parsing macros.
101+ /// Similar to `tokenstream::TokenTree`, except that `Sequence `, `MetaVar `, `MetaVarDecl`, and
102+ /// `MetaVarExpr ` are "first-class" token trees. Useful for parsing macros.
78103#[ derive( Debug , Clone , PartialEq , Encodable , Decodable ) ]
79104enum TokenTree {
80105 Token ( Token ) ,
106+ /// A delimited sequence, e.g. `($e:expr)` (RHS) or `{ $e }` (LHS).
81107 Delimited ( DelimSpan , Lrc < Delimited > ) ,
82- /// A kleene-style repetition sequence
108+ /// A kleene-style repetition sequence, e.g. `$($e:expr)*` (RHS) or `$($e),*` (LHS).
83109 Sequence ( DelimSpan , Lrc < SequenceRepetition > ) ,
84- /// e.g., `$var`
110+ /// e.g., `$var`.
85111 MetaVar ( Span , Ident ) ,
86- /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros .
112+ /// e.g., `$var:expr`. Only appears on the LHS .
87113 MetaVarDecl ( Span , Ident /* name to bind */ , Option < NonterminalKind > ) ,
88- /// A meta-variable expression inside `${...}`
114+ /// A meta-variable expression inside `${...}`.
89115 MetaVarExpr ( DelimSpan , MetaVarExpr ) ,
90116}
91117
92118impl TokenTree {
93- /// Return the number of tokens in the tree.
94- fn len ( & self ) -> usize {
95- match * self {
96- TokenTree :: Delimited ( _, ref delimed) => match delimed. delim {
97- token:: NoDelim => delimed. tts . len ( ) ,
98- _ => delimed. tts . len ( ) + 2 ,
99- } ,
100- TokenTree :: Sequence ( _, ref seq) => seq. tts . len ( ) ,
101- _ => 0 ,
102- }
103- }
104-
105119 /// Returns `true` if the given token tree is delimited.
106120 fn is_delimited ( & self ) -> bool {
107121 matches ! ( * self , TokenTree :: Delimited ( ..) )
@@ -115,26 +129,6 @@ impl TokenTree {
115129 }
116130 }
117131
118- /// Gets the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
119- fn get_tt ( & self , index : usize ) -> TokenTree {
120- match ( self , index) {
121- ( & TokenTree :: Delimited ( _, ref delimed) , _) if delimed. delim == token:: NoDelim => {
122- delimed. tts [ index] . clone ( )
123- }
124- ( & TokenTree :: Delimited ( span, ref delimed) , _) => {
125- if index == 0 {
126- return delimed. open_tt ( span) ;
127- }
128- if index == delimed. tts . len ( ) + 1 {
129- return delimed. close_tt ( span) ;
130- }
131- delimed. tts [ index - 1 ] . clone ( )
132- }
133- ( & TokenTree :: Sequence ( _, ref seq) , _) => seq. tts [ index] . clone ( ) ,
134- _ => panic ! ( "Cannot expand a token tree" ) ,
135- }
136- }
137-
138132 /// Retrieves the `TokenTree`'s span.
139133 fn span ( & self ) -> Span {
140134 match * self {
0 commit comments