72
72
73
73
crate use NamedMatch :: * ;
74
74
crate use ParseResult :: * ;
75
- use TokenTreeOrTokenTreeSlice :: * ;
76
75
77
- use crate :: mbe:: { self , DelimSpan , SequenceRepetition , TokenTree } ;
76
+ use crate :: mbe:: { self , SequenceRepetition , TokenTree } ;
78
77
79
78
use rustc_ast:: token:: { self , DocComment , Nonterminal , Token } ;
80
79
use rustc_parse:: parser:: Parser ;
@@ -90,43 +89,14 @@ use std::borrow::Cow;
90
89
use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
91
90
use std:: mem;
92
91
93
- // To avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body.
94
-
95
- /// Either a slice of token trees or a single one. This is used as the representation of the
96
- /// token trees that make up a matcher.
97
- #[ derive( Clone ) ]
98
- enum TokenTreeOrTokenTreeSlice < ' tt > {
99
- Tt ( TokenTree ) ,
100
- TtSlice ( & ' tt [ TokenTree ] ) ,
101
- }
102
-
103
- impl < ' tt > TokenTreeOrTokenTreeSlice < ' tt > {
104
- /// Returns the number of constituent top-level token trees of `self` (top-level in that it
105
- /// will not recursively descend into subtrees).
106
- fn len ( & self ) -> usize {
107
- match * self {
108
- TtSlice ( ref v) => v. len ( ) ,
109
- Tt ( ref tt) => tt. len ( ) ,
110
- }
111
- }
112
-
113
- /// The `index`-th token tree of `self`.
114
- fn get_tt ( & self , index : usize ) -> TokenTree {
115
- match * self {
116
- TtSlice ( ref v) => v[ index] . clone ( ) ,
117
- Tt ( ref tt) => tt. get_tt ( index) ,
118
- }
119
- }
120
- }
121
-
122
92
/// An unzipping of `TokenTree`s... see the `stack` field of `MatcherPos`.
123
93
///
124
94
/// This is used by `parse_tt_inner` to keep track of delimited submatchers that we have
125
95
/// descended into.
126
96
#[ derive( Clone ) ]
127
97
struct MatcherTtFrame < ' tt > {
128
98
/// The "parent" matcher that we are descending into.
129
- elts : TokenTreeOrTokenTreeSlice < ' tt > ,
99
+ elts : & ' tt [ TokenTree ] ,
130
100
/// The position of the "dot" in `elts` at the time we descended.
131
101
idx : usize ,
132
102
}
@@ -138,7 +108,7 @@ type NamedMatchVec = SmallVec<[NamedMatch; 4]>;
138
108
#[ derive( Clone ) ]
139
109
struct MatcherPos < ' tt > {
140
110
/// The token or slice of tokens that make up the matcher. `elts` is short for "elements".
141
- top_elts : TokenTreeOrTokenTreeSlice < ' tt > ,
111
+ top_elts : & ' tt [ TokenTree ] ,
142
112
143
113
/// The position of the "dot" in this matcher
144
114
idx : usize ,
@@ -183,7 +153,7 @@ struct MatcherPos<'tt> {
183
153
184
154
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
185
155
#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
186
- rustc_data_structures:: static_assert_size!( MatcherPos <' _>, 232 ) ;
156
+ rustc_data_structures:: static_assert_size!( MatcherPos <' _>, 136 ) ;
187
157
188
158
impl < ' tt > MatcherPos < ' tt > {
189
159
/// `len` `Vec`s (initially shared and empty) that will store matches of metavars.
@@ -203,7 +173,7 @@ impl<'tt> MatcherPos<'tt> {
203
173
let match_idx_hi = count_names ( ms) ;
204
174
MatcherPos {
205
175
// Start with the top level matcher given to us.
206
- top_elts : TtSlice ( ms ) ,
176
+ top_elts : ms ,
207
177
208
178
// The "dot" is before the first token of the matcher.
209
179
idx : 0 ,
@@ -224,9 +194,9 @@ impl<'tt> MatcherPos<'tt> {
224
194
}
225
195
}
226
196
227
- fn repetition ( up : Box < MatcherPos < ' tt > > , sp : DelimSpan , seq : Lrc < SequenceRepetition > ) -> Self {
197
+ fn repetition ( up : Box < MatcherPos < ' tt > > , seq : & ' tt SequenceRepetition ) -> Self {
228
198
MatcherPos {
229
- stack : smallvec ! [ ] ,
199
+ top_elts : & seq . tts ,
230
200
idx : 0 ,
231
201
matches : Self :: create_matches ( up. matches . len ( ) ) ,
232
202
match_lo : up. match_cur ,
@@ -237,7 +207,7 @@ impl<'tt> MatcherPos<'tt> {
237
207
sep : seq. separator . clone ( ) ,
238
208
seq_op : seq. kleene . op ,
239
209
} ) ,
240
- top_elts : Tt ( TokenTree :: Sequence ( sp , seq ) ) ,
210
+ stack : smallvec ! [ ] ,
241
211
}
242
212
}
243
213
@@ -288,8 +258,8 @@ crate type NamedParseResult = ParseResult<FxHashMap<MacroRulesNormalizedIdent, N
288
258
pub ( super ) fn count_names ( ms : & [ TokenTree ] ) -> usize {
289
259
ms. iter ( ) . fold ( 0 , |count, elt| {
290
260
count
291
- + match * elt {
292
- TokenTree :: Delimited ( _, ref delim) => count_names ( & delim. tts ) ,
261
+ + match elt {
262
+ TokenTree :: Delimited ( _, delim) => count_names ( delim. inner_tts ( ) ) ,
293
263
TokenTree :: MetaVar ( ..) => 0 ,
294
264
TokenTree :: MetaVarDecl ( ..) => 1 ,
295
265
// Panicking here would abort execution because `parse_tree` makes use of this
@@ -298,7 +268,7 @@ pub(super) fn count_names(ms: &[TokenTree]) -> usize {
298
268
// `0` is still returned to inform that no meta-variable was found. `Meta-variables
299
269
// != Meta-variable expressions`
300
270
TokenTree :: MetaVarExpr ( ..) => 0 ,
301
- TokenTree :: Sequence ( _, ref seq) => seq. num_captures ,
271
+ TokenTree :: Sequence ( _, seq) => seq. num_captures ,
302
272
TokenTree :: Token ( ..) => 0 ,
303
273
}
304
274
} )
@@ -382,7 +352,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
382
352
}
383
353
}
384
354
TokenTree :: Delimited ( _, ref delim) => {
385
- for next_m in & delim. tts {
355
+ for next_m in delim. inner_tts ( ) {
386
356
n_rec ( sess, next_m, res. by_ref ( ) , ret_val) ?;
387
357
}
388
358
}
@@ -446,8 +416,8 @@ pub struct TtParser<'tt> {
446
416
}
447
417
448
418
impl < ' tt > TtParser < ' tt > {
449
- pub ( super ) fn new ( macro_name : Ident ) -> Self {
450
- Self { macro_name, cur_items : vec ! [ ] , next_items : vec ! [ ] , bb_items : vec ! [ ] }
419
+ pub ( super ) fn new ( macro_name : Ident ) -> TtParser < ' tt > {
420
+ TtParser { macro_name, cur_items : vec ! [ ] , next_items : vec ! [ ] , bb_items : vec ! [ ] }
451
421
}
452
422
453
423
/// Process the matcher positions of `cur_items` until it is empty. In the process, this will
@@ -492,8 +462,8 @@ impl<'tt> TtParser<'tt> {
492
462
if idx < len {
493
463
// We are in the middle of a matcher. Compare the matcher's current tt against
494
464
// `token`.
495
- match item. top_elts . get_tt ( idx) {
496
- TokenTree :: Sequence ( sp , seq) => {
465
+ match & item. top_elts [ idx] {
466
+ TokenTree :: Sequence ( _sp , seq) => {
497
467
let op = seq. kleene . op ;
498
468
if op == mbe:: KleeneOp :: ZeroOrMore || op == mbe:: KleeneOp :: ZeroOrOne {
499
469
// Allow for the possibility of zero matches of this sequence.
@@ -507,17 +477,17 @@ impl<'tt> TtParser<'tt> {
507
477
}
508
478
509
479
// Allow for the possibility of one or more matches of this sequence.
510
- self . cur_items . push ( box MatcherPos :: repetition ( item, sp , seq) ) ;
480
+ self . cur_items . push ( box MatcherPos :: repetition ( item, & seq) ) ;
511
481
}
512
482
513
- TokenTree :: MetaVarDecl ( span, _, None ) => {
483
+ & TokenTree :: MetaVarDecl ( span, _, None ) => {
514
484
// E.g. `$e` instead of `$e:expr`.
515
485
if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) . is_some ( ) {
516
486
return Some ( Error ( span, "missing fragment specifier" . to_string ( ) ) ) ;
517
487
}
518
488
}
519
489
520
- TokenTree :: MetaVarDecl ( _, _, Some ( kind) ) => {
490
+ & TokenTree :: MetaVarDecl ( _, _, Some ( kind) ) => {
521
491
// Built-in nonterminals never start with these tokens, so we can eliminate
522
492
// them from consideration.
523
493
//
@@ -528,13 +498,14 @@ impl<'tt> TtParser<'tt> {
528
498
}
529
499
}
530
500
531
- seq @ TokenTree :: Delimited ( .. ) => {
501
+ TokenTree :: Delimited ( _ , delimited ) => {
532
502
// To descend into a delimited submatcher, we push the current matcher onto
533
503
// a stack and push a new item containing the submatcher onto `cur_items`.
534
504
//
535
505
// At the beginning of the loop, if we reach the end of the delimited
536
- // submatcher, we pop the stack to backtrack out of the descent.
537
- let lower_elts = mem:: replace ( & mut item. top_elts , Tt ( seq) ) ;
506
+ // submatcher, we pop the stack to backtrack out of the descent. Note that
507
+ // we use `all_tts` to include the open and close delimiter tokens.
508
+ let lower_elts = mem:: replace ( & mut item. top_elts , & delimited. all_tts ) ;
538
509
let idx = item. idx ;
539
510
item. stack . push ( MatcherTtFrame { elts : lower_elts, idx } ) ;
540
511
item. idx = 0 ;
@@ -560,7 +531,6 @@ impl<'tt> TtParser<'tt> {
560
531
} else if let Some ( repetition) = & item. repetition {
561
532
// We are past the end of a repetition.
562
533
debug_assert ! ( idx <= len + 1 ) ;
563
- debug_assert ! ( matches!( item. top_elts, Tt ( TokenTree :: Sequence ( ..) ) ) ) ;
564
534
565
535
if idx == len {
566
536
// Add all matches from the sequence to `up`, and move the "dot" past the
@@ -678,9 +648,7 @@ impl<'tt> TtParser<'tt> {
678
648
( 0 , 1 ) => {
679
649
// We need to call the black-box parser to get some nonterminal.
680
650
let mut item = self . bb_items . pop ( ) . unwrap ( ) ;
681
- if let TokenTree :: MetaVarDecl ( span, _, Some ( kind) ) =
682
- item. top_elts . get_tt ( item. idx )
683
- {
651
+ if let TokenTree :: MetaVarDecl ( span, _, Some ( kind) ) = item. top_elts [ item. idx ] {
684
652
let match_cur = item. match_cur ;
685
653
// We use the span of the metavariable declaration to determine any
686
654
// edition-specific matching behavior for non-terminals.
@@ -720,7 +688,7 @@ impl<'tt> TtParser<'tt> {
720
688
let nts = self
721
689
. bb_items
722
690
. iter ( )
723
- . map ( |item| match item. top_elts . get_tt ( item. idx ) {
691
+ . map ( |item| match item. top_elts [ item. idx ] {
724
692
TokenTree :: MetaVarDecl ( _, bind, Some ( kind) ) => {
725
693
format ! ( "{} ('{}')" , kind, bind)
726
694
}
0 commit comments