@@ -137,13 +137,8 @@ impl TokenTree {
137
137
/// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
138
138
/// instead of a representation of the abstract syntax tree.
139
139
/// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat.
140
- ///
141
- /// The use of `Option` is an optimization that avoids the need for an
142
- /// allocation when the stream is empty. However, it is not guaranteed that an
143
- /// empty stream is represented with `None`; it may be represented as a `Some`
144
- /// around an empty `Vec`.
145
- #[ derive( Clone , Debug ) ]
146
- pub struct TokenStream ( pub Option < Lrc < Vec < TreeAndJoint > > > ) ;
140
+ #[ derive( Clone , Debug , Default ) ]
141
+ pub struct TokenStream ( pub Lrc < Vec < TreeAndJoint > > ) ;
147
142
148
143
pub type TreeAndJoint = ( TokenTree , IsJoint ) ;
149
144
@@ -164,36 +159,34 @@ impl TokenStream {
164
159
/// separating the two arguments with a comma for diagnostic suggestions.
165
160
pub ( crate ) fn add_comma ( & self ) -> Option < ( TokenStream , Span ) > {
166
161
// Used to suggest if a user writes `foo!(a b);`
167
- if let Some ( ref stream) = self . 0 {
168
- let mut suggestion = None ;
169
- let mut iter = stream. iter ( ) . enumerate ( ) . peekable ( ) ;
170
- while let Some ( ( pos, ts) ) = iter. next ( ) {
171
- if let Some ( ( _, next) ) = iter. peek ( ) {
172
- let sp = match ( & ts, & next) {
173
- ( _, ( TokenTree :: Token ( Token { kind : token:: Comma , .. } ) , _) ) => continue ,
174
- ( ( TokenTree :: Token ( token_left) , NonJoint ) ,
175
- ( TokenTree :: Token ( token_right) , _) )
176
- if ( ( token_left. is_ident ( ) && !token_left. is_reserved_ident ( ) )
177
- || token_left. is_lit ( ) ) &&
178
- ( ( token_right. is_ident ( ) && !token_right. is_reserved_ident ( ) )
179
- || token_right. is_lit ( ) ) => token_left. span ,
180
- ( ( TokenTree :: Delimited ( sp, ..) , NonJoint ) , _) => sp. entire ( ) ,
181
- _ => continue ,
182
- } ;
183
- let sp = sp. shrink_to_hi ( ) ;
184
- let comma = ( TokenTree :: token ( token:: Comma , sp) , NonJoint ) ;
185
- suggestion = Some ( ( pos, comma, sp) ) ;
186
- }
187
- }
188
- if let Some ( ( pos, comma, sp) ) = suggestion {
189
- let mut new_stream = vec ! [ ] ;
190
- let parts = stream. split_at ( pos + 1 ) ;
191
- new_stream. extend_from_slice ( parts. 0 ) ;
192
- new_stream. push ( comma) ;
193
- new_stream. extend_from_slice ( parts. 1 ) ;
194
- return Some ( ( TokenStream :: new ( new_stream) , sp) ) ;
162
+ let mut suggestion = None ;
163
+ let mut iter = self . 0 . iter ( ) . enumerate ( ) . peekable ( ) ;
164
+ while let Some ( ( pos, ts) ) = iter. next ( ) {
165
+ if let Some ( ( _, next) ) = iter. peek ( ) {
166
+ let sp = match ( & ts, & next) {
167
+ ( _, ( TokenTree :: Token ( Token { kind : token:: Comma , .. } ) , _) ) => continue ,
168
+ ( ( TokenTree :: Token ( token_left) , NonJoint ) ,
169
+ ( TokenTree :: Token ( token_right) , _) )
170
+ if ( ( token_left. is_ident ( ) && !token_left. is_reserved_ident ( ) )
171
+ || token_left. is_lit ( ) ) &&
172
+ ( ( token_right. is_ident ( ) && !token_right. is_reserved_ident ( ) )
173
+ || token_right. is_lit ( ) ) => token_left. span ,
174
+ ( ( TokenTree :: Delimited ( sp, ..) , NonJoint ) , _) => sp. entire ( ) ,
175
+ _ => continue ,
176
+ } ;
177
+ let sp = sp. shrink_to_hi ( ) ;
178
+ let comma = ( TokenTree :: token ( token:: Comma , sp) , NonJoint ) ;
179
+ suggestion = Some ( ( pos, comma, sp) ) ;
195
180
}
196
181
}
182
+ if let Some ( ( pos, comma, sp) ) = suggestion {
183
+ let mut new_stream = vec ! [ ] ;
184
+ let parts = self . 0 . split_at ( pos + 1 ) ;
185
+ new_stream. extend_from_slice ( parts. 0 ) ;
186
+ new_stream. push ( comma) ;
187
+ new_stream. extend_from_slice ( parts. 1 ) ;
188
+ return Some ( ( TokenStream :: new ( new_stream) , sp) ) ;
189
+ }
197
190
None
198
191
}
199
192
}
@@ -225,28 +218,21 @@ impl PartialEq<TokenStream> for TokenStream {
225
218
}
226
219
227
220
impl TokenStream {
228
- pub fn len ( & self ) -> usize {
229
- if let Some ( ref slice) = self . 0 {
230
- slice. len ( )
231
- } else {
232
- 0
233
- }
221
+ pub fn new ( streams : Vec < TreeAndJoint > ) -> TokenStream {
222
+ TokenStream ( Lrc :: new ( streams) )
234
223
}
235
224
236
- pub fn empty ( ) -> TokenStream {
237
- TokenStream ( None )
225
+ pub fn is_empty ( & self ) -> bool {
226
+ self . 0 . is_empty ( )
238
227
}
239
228
240
- pub fn is_empty ( & self ) -> bool {
241
- match self . 0 {
242
- None => true ,
243
- Some ( ref stream) => stream. is_empty ( ) ,
244
- }
229
+ pub fn len ( & self ) -> usize {
230
+ self . 0 . len ( )
245
231
}
246
232
247
233
pub ( crate ) fn from_streams ( mut streams : SmallVec < [ TokenStream ; 2 ] > ) -> TokenStream {
248
234
match streams. len ( ) {
249
- 0 => TokenStream :: empty ( ) ,
235
+ 0 => TokenStream :: default ( ) ,
250
236
1 => streams. pop ( ) . unwrap ( ) ,
251
237
_ => {
252
238
// We are going to extend the first stream in `streams` with
@@ -270,41 +256,24 @@ impl TokenStream {
270
256
// Get the first stream. If it's `None`, create an empty
271
257
// stream.
272
258
let mut iter = streams. drain ( ) ;
273
- let mut first_stream_lrc = match iter. next ( ) . unwrap ( ) . 0 {
274
- Some ( first_stream_lrc) => first_stream_lrc,
275
- None => Lrc :: new ( vec ! [ ] ) ,
276
- } ;
259
+ let mut first_stream_lrc = iter. next ( ) . unwrap ( ) . 0 ;
277
260
278
261
// Append the elements to the first stream, after reserving
279
262
// space for them.
280
263
let first_vec_mut = Lrc :: make_mut ( & mut first_stream_lrc) ;
281
264
first_vec_mut. reserve ( num_appends) ;
282
265
for stream in iter {
283
- if let Some ( stream) = stream. 0 {
284
- first_vec_mut. extend ( stream. iter ( ) . cloned ( ) ) ;
285
- }
266
+ first_vec_mut. extend ( stream. 0 . iter ( ) . cloned ( ) ) ;
286
267
}
287
268
288
269
// Create the final `TokenStream`.
289
- match first_vec_mut. len ( ) {
290
- 0 => TokenStream ( None ) ,
291
- _ => TokenStream ( Some ( first_stream_lrc) ) ,
292
- }
270
+ TokenStream ( first_stream_lrc)
293
271
}
294
272
}
295
273
}
296
274
297
- pub fn new ( streams : Vec < TreeAndJoint > ) -> TokenStream {
298
- match streams. len ( ) {
299
- 0 => TokenStream ( None ) ,
300
- _ => TokenStream ( Some ( Lrc :: new ( streams) ) ) ,
301
- }
302
- }
303
-
304
275
pub fn append_to_tree_and_joint_vec ( self , vec : & mut Vec < TreeAndJoint > ) {
305
- if let Some ( stream) = self . 0 {
306
- vec. extend ( stream. iter ( ) . cloned ( ) ) ;
307
- }
276
+ vec. extend ( self . 0 . iter ( ) . cloned ( ) ) ;
308
277
}
309
278
310
279
pub fn trees ( & self ) -> Cursor {
@@ -371,24 +340,22 @@ impl TokenStream {
371
340
}
372
341
373
342
pub fn map_enumerated < F : FnMut ( usize , TokenTree ) -> TokenTree > ( self , mut f : F ) -> TokenStream {
374
- TokenStream ( self . 0 . map ( |stream| {
375
- Lrc :: new (
376
- stream
377
- . iter ( )
378
- . enumerate ( )
379
- . map ( |( i, ( tree, is_joint) ) | ( f ( i, tree. clone ( ) ) , * is_joint) )
380
- . collect ( ) )
381
- } ) )
343
+ TokenStream ( Lrc :: new (
344
+ self . 0
345
+ . iter ( )
346
+ . enumerate ( )
347
+ . map ( |( i, ( tree, is_joint) ) | ( f ( i, tree. clone ( ) ) , * is_joint) )
348
+ . collect ( )
349
+ ) )
382
350
}
383
351
384
352
pub fn map < F : FnMut ( TokenTree ) -> TokenTree > ( self , mut f : F ) -> TokenStream {
385
- TokenStream ( self . 0 . map ( |stream| {
386
- Lrc :: new (
387
- stream
388
- . iter ( )
389
- . map ( |( tree, is_joint) | ( f ( tree. clone ( ) ) , * is_joint) )
390
- . collect ( ) )
391
- } ) )
353
+ TokenStream ( Lrc :: new (
354
+ self . 0
355
+ . iter ( )
356
+ . map ( |( tree, is_joint) | ( f ( tree. clone ( ) ) , * is_joint) )
357
+ . collect ( )
358
+ ) )
392
359
}
393
360
}
394
361
@@ -406,44 +373,43 @@ impl TokenStreamBuilder {
406
373
407
374
// If `self` is not empty and the last tree within the last stream is a
408
375
// token tree marked with `Joint`...
409
- if let Some ( TokenStream ( Some ( ref mut last_stream_lrc) ) ) = self . 0 . last_mut ( ) {
376
+ if let Some ( TokenStream ( ref mut last_stream_lrc) ) = self . 0 . last_mut ( ) {
410
377
if let Some ( ( TokenTree :: Token ( last_token) , Joint ) ) = last_stream_lrc. last ( ) {
411
378
412
379
// ...and `stream` is not empty and the first tree within it is
413
380
// a token tree...
414
- if let TokenStream ( Some ( ref mut stream_lrc) ) = stream {
415
- if let Some ( ( TokenTree :: Token ( token) , is_joint) ) = stream_lrc. first ( ) {
416
-
417
- // ...and the two tokens can be glued together...
418
- if let Some ( glued_tok) = last_token. glue ( & token) {
419
-
420
- // ...then do so, by overwriting the last token
421
- // tree in `self` and removing the first token tree
422
- // from `stream`. This requires using `make_mut()`
423
- // on the last stream in `self` and on `stream`,
424
- // and in practice this doesn't cause cloning 99.9%
425
- // of the time.
426
-
427
- // Overwrite the last token tree with the merged
428
- // token.
429
- let last_vec_mut = Lrc :: make_mut ( last_stream_lrc) ;
430
- * last_vec_mut. last_mut ( ) . unwrap ( ) =
431
- ( TokenTree :: Token ( glued_tok) , * is_joint) ;
432
-
433
- // Remove the first token tree from `stream`. (This
434
- // is almost always the only tree in `stream`.)
435
- let stream_vec_mut = Lrc :: make_mut ( stream_lrc) ;
436
- stream_vec_mut. remove ( 0 ) ;
437
-
438
- // Don't push `stream` if it's empty -- that could
439
- // block subsequent token gluing, by getting
440
- // between two token trees that should be glued
441
- // together.
442
- if !stream. is_empty ( ) {
443
- self . 0 . push ( stream) ;
444
- }
445
- return ;
381
+ let TokenStream ( ref mut stream_lrc) = stream;
382
+ if let Some ( ( TokenTree :: Token ( token) , is_joint) ) = stream_lrc. first ( ) {
383
+
384
+ // ...and the two tokens can be glued together...
385
+ if let Some ( glued_tok) = last_token. glue ( & token) {
386
+
387
+ // ...then do so, by overwriting the last token
388
+ // tree in `self` and removing the first token tree
389
+ // from `stream`. This requires using `make_mut()`
390
+ // on the last stream in `self` and on `stream`,
391
+ // and in practice this doesn't cause cloning 99.9%
392
+ // of the time.
393
+
394
+ // Overwrite the last token tree with the merged
395
+ // token.
396
+ let last_vec_mut = Lrc :: make_mut ( last_stream_lrc) ;
397
+ * last_vec_mut. last_mut ( ) . unwrap ( ) =
398
+ ( TokenTree :: Token ( glued_tok) , * is_joint) ;
399
+
400
+ // Remove the first token tree from `stream`. (This
401
+ // is almost always the only tree in `stream`.)
402
+ let stream_vec_mut = Lrc :: make_mut ( stream_lrc) ;
403
+ stream_vec_mut. remove ( 0 ) ;
404
+
405
+ // Don't push `stream` if it's empty -- that could
406
+ // block subsequent token gluing, by getting
407
+ // between two token trees that should be glued
408
+ // together.
409
+ if !stream. is_empty ( ) {
410
+ self . 0 . push ( stream) ;
446
411
}
412
+ return ;
447
413
}
448
414
}
449
415
}
@@ -476,16 +442,11 @@ impl Cursor {
476
442
}
477
443
478
444
pub fn next_with_joint ( & mut self ) -> Option < TreeAndJoint > {
479
- match self . stream . 0 {
480
- None => None ,
481
- Some ( ref stream) => {
482
- if self . index < stream. len ( ) {
483
- self . index += 1 ;
484
- Some ( stream[ self . index - 1 ] . clone ( ) )
485
- } else {
486
- None
487
- }
488
- }
445
+ if self . index < self . stream . len ( ) {
446
+ self . index += 1 ;
447
+ Some ( self . stream . 0 [ self . index - 1 ] . clone ( ) )
448
+ } else {
449
+ None
489
450
}
490
451
}
491
452
@@ -494,16 +455,13 @@ impl Cursor {
494
455
return ;
495
456
}
496
457
let index = self . index ;
497
- let stream = mem:: replace ( & mut self . stream , TokenStream ( None ) ) ;
458
+ let stream = mem:: take ( & mut self . stream ) ;
498
459
* self = TokenStream :: from_streams ( smallvec ! [ stream, new_stream] ) . into_trees ( ) ;
499
460
self . index = index;
500
461
}
501
462
502
463
pub fn look_ahead ( & self , n : usize ) -> Option < TokenTree > {
503
- match self . stream . 0 {
504
- None => None ,
505
- Some ( ref stream) => stream[ self . index ..] . get ( n) . map ( |( tree, _) | tree. clone ( ) ) ,
506
- }
464
+ self . stream . 0 [ self . index ..] . get ( n) . map ( |( tree, _) | tree. clone ( ) )
507
465
}
508
466
}
509
467
0 commit comments