@@ -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