@@ -17,23 +17,48 @@ use rustc_data_structures::sync::Lrc;
17
17
use rustc_span:: symbol:: Ident ;
18
18
use rustc_span:: Span ;
19
19
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`.
22
22
#[ derive( Clone , PartialEq , Encodable , Decodable , Debug ) ]
23
23
struct Delimited {
24
24
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 > ,
26
29
}
27
30
28
31
impl 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
32
52
}
33
53
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 ]
37
62
}
38
63
}
39
64
@@ -73,35 +98,24 @@ enum KleeneOp {
73
98
ZeroOrOne ,
74
99
}
75
100
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.
78
103
#[ derive( Debug , Clone , PartialEq , Encodable , Decodable ) ]
79
104
enum TokenTree {
80
105
Token ( Token ) ,
106
+ /// A delimited sequence, e.g. `($e:expr)` (RHS) or `{ $e }` (LHS).
81
107
Delimited ( DelimSpan , Lrc < Delimited > ) ,
82
- /// A kleene-style repetition sequence
108
+ /// A kleene-style repetition sequence, e.g. `$($e:expr)*` (RHS) or `$($e),*` (LHS).
83
109
Sequence ( DelimSpan , Lrc < SequenceRepetition > ) ,
84
- /// e.g., `$var`
110
+ /// e.g., `$var`.
85
111
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 .
87
113
MetaVarDecl ( Span , Ident /* name to bind */ , Option < NonterminalKind > ) ,
88
- /// A meta-variable expression inside `${...}`
114
+ /// A meta-variable expression inside `${...}`.
89
115
MetaVarExpr ( DelimSpan , MetaVarExpr ) ,
90
116
}
91
117
92
118
impl 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
-
105
119
/// Returns `true` if the given token tree is delimited.
106
120
fn is_delimited ( & self ) -> bool {
107
121
matches ! ( * self , TokenTree :: Delimited ( ..) )
@@ -115,26 +129,6 @@ impl TokenTree {
115
129
}
116
130
}
117
131
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
-
138
132
/// Retrieves the `TokenTree`'s span.
139
133
fn span ( & self ) -> Span {
140
134
match * self {
0 commit comments