@@ -141,11 +141,13 @@ impl TokenTree {
141
141
/// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
142
142
/// instead of a representation of the abstract syntax tree.
143
143
/// Today's `TokenTree`s can still contain AST via `Token::Interpolated` for back-compat.
144
+ ///
145
+ /// The use of `Option` is an optimization that avoids the need for an
146
+ /// allocation when the stream is empty. However, it is not guaranteed that an
147
+ /// empty stream is represented with `None`; it may be represented as a `Some`
148
+ /// around an empty `Vec`.
144
149
#[ derive( Clone , Debug ) ]
145
- pub enum TokenStream {
146
- Empty ,
147
- Stream ( Lrc < Vec < TreeAndJoint > > ) ,
148
- }
150
+ pub struct TokenStream ( Option < Lrc < Vec < TreeAndJoint > > > ) ;
149
151
150
152
pub type TreeAndJoint = ( TokenTree , IsJoint ) ;
151
153
@@ -166,7 +168,7 @@ impl TokenStream {
166
168
/// separating the two arguments with a comma for diagnostic suggestions.
167
169
pub ( crate ) fn add_comma ( & self ) -> Option < ( TokenStream , Span ) > {
168
170
// Used to suggest if a user writes `foo!(a b);`
169
- if let TokenStream :: Stream ( ref stream) = self {
171
+ if let Some ( ref stream) = self . 0 {
170
172
let mut suggestion = None ;
171
173
let mut iter = stream. iter ( ) . enumerate ( ) . peekable ( ) ;
172
174
while let Some ( ( pos, ts) ) = iter. next ( ) {
@@ -230,21 +232,21 @@ impl PartialEq<TokenStream> for TokenStream {
230
232
231
233
impl TokenStream {
232
234
pub fn len ( & self ) -> usize {
233
- if let TokenStream :: Stream ( ref slice) = self {
235
+ if let Some ( ref slice) = self . 0 {
234
236
slice. len ( )
235
237
} else {
236
238
0
237
239
}
238
240
}
239
241
240
242
pub fn empty ( ) -> TokenStream {
241
- TokenStream :: Empty
243
+ TokenStream ( None )
242
244
}
243
245
244
246
pub fn is_empty ( & self ) -> bool {
245
- match self {
246
- TokenStream :: Empty => true ,
247
- _ => false ,
247
+ match self . 0 {
248
+ None => true ,
249
+ Some ( ref stream ) => stream . is_empty ( ) ,
248
250
}
249
251
}
250
252
@@ -255,9 +257,9 @@ impl TokenStream {
255
257
_ => {
256
258
let mut vec = vec ! [ ] ;
257
259
for stream in streams {
258
- match stream {
259
- TokenStream :: Empty => { } ,
260
- TokenStream :: Stream ( stream2) => vec. extend ( stream2. iter ( ) . cloned ( ) ) ,
260
+ match stream. 0 {
261
+ None => { } ,
262
+ Some ( stream2) => vec. extend ( stream2. iter ( ) . cloned ( ) ) ,
261
263
}
262
264
}
263
265
TokenStream :: new ( vec)
@@ -267,15 +269,14 @@ impl TokenStream {
267
269
268
270
pub fn new ( streams : Vec < TreeAndJoint > ) -> TokenStream {
269
271
match streams. len ( ) {
270
- 0 => TokenStream :: empty ( ) ,
271
- _ => TokenStream :: Stream ( Lrc :: new ( streams) ) ,
272
+ 0 => TokenStream ( None ) ,
273
+ _ => TokenStream ( Some ( Lrc :: new ( streams) ) ) ,
272
274
}
273
275
}
274
276
275
277
pub fn append_to_tree_and_joint_vec ( self , vec : & mut Vec < TreeAndJoint > ) {
276
- match self {
277
- TokenStream :: Empty => { }
278
- TokenStream :: Stream ( stream) => vec. extend ( stream. iter ( ) . cloned ( ) ) ,
278
+ if let Some ( stream) = self . 0 {
279
+ vec. extend ( stream. iter ( ) . cloned ( ) ) ;
279
280
}
280
281
}
281
282
@@ -340,41 +341,36 @@ impl TokenStream {
340
341
}
341
342
342
343
pub fn map_enumerated < F : FnMut ( usize , TokenTree ) -> TokenTree > ( self , mut f : F ) -> TokenStream {
343
- match self {
344
- TokenStream :: Empty => TokenStream :: Empty ,
345
- TokenStream :: Stream ( stream) => TokenStream :: Stream ( Lrc :: new (
344
+ TokenStream ( self . 0 . map ( |stream| {
345
+ Lrc :: new (
346
346
stream
347
347
. iter ( )
348
348
. enumerate ( )
349
349
. map ( |( i, ( tree, is_joint) ) | ( f ( i, tree. clone ( ) ) , * is_joint) )
350
- . collect ( )
351
- ) ) ,
352
- }
350
+ . collect ( ) )
351
+ } ) )
353
352
}
354
353
355
354
pub fn map < F : FnMut ( TokenTree ) -> TokenTree > ( self , mut f : F ) -> TokenStream {
356
- match self {
357
- TokenStream :: Empty => TokenStream :: Empty ,
358
- TokenStream :: Stream ( stream) => TokenStream :: Stream ( Lrc :: new (
355
+ TokenStream ( self . 0 . map ( |stream| {
356
+ Lrc :: new (
359
357
stream
360
358
. iter ( )
361
359
. map ( |( tree, is_joint) | ( f ( tree. clone ( ) ) , * is_joint) )
362
- . collect ( )
363
- ) ) ,
364
- }
360
+ . collect ( ) )
361
+ } ) )
365
362
}
366
363
367
- fn first_tree_and_joint ( & self ) -> Option < ( TokenTree , IsJoint ) > {
368
- match self {
369
- TokenStream :: Empty => None ,
370
- TokenStream :: Stream ( ref stream) => Some ( stream. first ( ) . unwrap ( ) . clone ( ) )
371
- }
364
+ fn first_tree_and_joint ( & self ) -> Option < TreeAndJoint > {
365
+ self . 0 . as_ref ( ) . map ( |stream| {
366
+ stream. first ( ) . unwrap ( ) . clone ( )
367
+ } )
372
368
}
373
369
374
370
fn last_tree_if_joint ( & self ) -> Option < TokenTree > {
375
- match self {
376
- TokenStream :: Empty => None ,
377
- TokenStream :: Stream ( ref stream) => {
371
+ match self . 0 {
372
+ None => None ,
373
+ Some ( ref stream) => {
378
374
if let ( tree, Joint ) = stream. last ( ) . unwrap ( ) {
379
375
Some ( tree. clone ( ) )
380
376
} else {
@@ -418,21 +414,21 @@ impl TokenStreamBuilder {
418
414
}
419
415
420
416
fn push_all_but_last_tree ( & mut self , stream : & TokenStream ) {
421
- if let TokenStream :: Stream ( ref streams) = stream {
417
+ if let Some ( ref streams) = stream. 0 {
422
418
let len = streams. len ( ) ;
423
419
match len {
424
420
1 => { }
425
- _ => self . 0 . push ( TokenStream :: Stream ( Lrc :: new ( streams[ 0 .. len - 1 ] . to_vec ( ) ) ) ) ,
421
+ _ => self . 0 . push ( TokenStream ( Some ( Lrc :: new ( streams[ 0 .. len - 1 ] . to_vec ( ) ) ) ) ) ,
426
422
}
427
423
}
428
424
}
429
425
430
426
fn push_all_but_first_tree ( & mut self , stream : & TokenStream ) {
431
- if let TokenStream :: Stream ( ref streams) = stream {
427
+ if let Some ( ref streams) = stream. 0 {
432
428
let len = streams. len ( ) ;
433
429
match len {
434
430
1 => { }
435
- _ => self . 0 . push ( TokenStream :: Stream ( Lrc :: new ( streams[ 1 .. len] . to_vec ( ) ) ) ) ,
431
+ _ => self . 0 . push ( TokenStream ( Some ( Lrc :: new ( streams[ 1 .. len] . to_vec ( ) ) ) ) ) ,
436
432
}
437
433
}
438
434
}
@@ -458,9 +454,9 @@ impl Cursor {
458
454
}
459
455
460
456
pub fn next_with_joint ( & mut self ) -> Option < TreeAndJoint > {
461
- match self . stream {
462
- TokenStream :: Empty => None ,
463
- TokenStream :: Stream ( ref stream) => {
457
+ match self . stream . 0 {
458
+ None => None ,
459
+ Some ( ref stream) => {
464
460
if self . index < stream. len ( ) {
465
461
self . index += 1 ;
466
462
Some ( stream[ self . index - 1 ] . clone ( ) )
@@ -476,16 +472,15 @@ impl Cursor {
476
472
return ;
477
473
}
478
474
let index = self . index ;
479
- let stream = mem:: replace ( & mut self . stream , TokenStream :: Empty ) ;
475
+ let stream = mem:: replace ( & mut self . stream , TokenStream ( None ) ) ;
480
476
* self = TokenStream :: from_streams ( vec ! [ stream, new_stream] ) . into_trees ( ) ;
481
477
self . index = index;
482
478
}
483
479
484
480
pub fn look_ahead ( & self , n : usize ) -> Option < TokenTree > {
485
- match self . stream {
486
- TokenStream :: Empty => None ,
487
- TokenStream :: Stream ( ref stream) =>
488
- stream[ self . index ..] . get ( n) . map ( |( tree, _) | tree. clone ( ) ) ,
481
+ match self . stream . 0 {
482
+ None => None ,
483
+ Some ( ref stream) => stream[ self . index ..] . get ( n) . map ( |( tree, _) | tree. clone ( ) ) ,
489
484
}
490
485
}
491
486
}
0 commit comments