@@ -141,11 +141,13 @@ impl TokenTree {
141141/// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
142142/// instead of a representation of the abstract syntax tree.
143143/// 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`.
144149#[ derive( Clone , Debug ) ]
145- pub enum TokenStream {
146- Empty ,
147- Stream ( Lrc < Vec < TreeAndJoint > > ) ,
148- }
150+ pub struct TokenStream ( Option < Lrc < Vec < TreeAndJoint > > > ) ;
149151
150152pub type TreeAndJoint = ( TokenTree , IsJoint ) ;
151153
@@ -166,7 +168,7 @@ impl TokenStream {
166168 /// separating the two arguments with a comma for diagnostic suggestions.
167169 pub ( crate ) fn add_comma ( & self ) -> Option < ( TokenStream , Span ) > {
168170 // 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 {
170172 let mut suggestion = None ;
171173 let mut iter = stream. iter ( ) . enumerate ( ) . peekable ( ) ;
172174 while let Some ( ( pos, ts) ) = iter. next ( ) {
@@ -230,21 +232,21 @@ impl PartialEq<TokenStream> for TokenStream {
230232
231233impl TokenStream {
232234 pub fn len ( & self ) -> usize {
233- if let TokenStream :: Stream ( ref slice) = self {
235+ if let Some ( ref slice) = self . 0 {
234236 slice. len ( )
235237 } else {
236238 0
237239 }
238240 }
239241
240242 pub fn empty ( ) -> TokenStream {
241- TokenStream :: Empty
243+ TokenStream ( None )
242244 }
243245
244246 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 ( ) ,
248250 }
249251 }
250252
@@ -255,9 +257,9 @@ impl TokenStream {
255257 _ => {
256258 let mut vec = vec ! [ ] ;
257259 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 ( ) ) ,
261263 }
262264 }
263265 TokenStream :: new ( vec)
@@ -267,15 +269,14 @@ impl TokenStream {
267269
268270 pub fn new ( streams : Vec < TreeAndJoint > ) -> TokenStream {
269271 match streams. len ( ) {
270- 0 => TokenStream :: empty ( ) ,
271- _ => TokenStream :: Stream ( Lrc :: new ( streams) ) ,
272+ 0 => TokenStream ( None ) ,
273+ _ => TokenStream ( Some ( Lrc :: new ( streams) ) ) ,
272274 }
273275 }
274276
275277 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 ( ) ) ;
279280 }
280281 }
281282
@@ -340,41 +341,36 @@ impl TokenStream {
340341 }
341342
342343 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 (
346346 stream
347347 . iter ( )
348348 . enumerate ( )
349349 . map ( |( i, ( tree, is_joint) ) | ( f ( i, tree. clone ( ) ) , * is_joint) )
350- . collect ( )
351- ) ) ,
352- }
350+ . collect ( ) )
351+ } ) )
353352 }
354353
355354 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 (
359357 stream
360358 . iter ( )
361359 . map ( |( tree, is_joint) | ( f ( tree. clone ( ) ) , * is_joint) )
362- . collect ( )
363- ) ) ,
364- }
360+ . collect ( ) )
361+ } ) )
365362 }
366363
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+ } )
372368 }
373369
374370 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) => {
378374 if let ( tree, Joint ) = stream. last ( ) . unwrap ( ) {
379375 Some ( tree. clone ( ) )
380376 } else {
@@ -418,21 +414,21 @@ impl TokenStreamBuilder {
418414 }
419415
420416 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 {
422418 let len = streams. len ( ) ;
423419 match len {
424420 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 ( ) ) ) ) ) ,
426422 }
427423 }
428424 }
429425
430426 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 {
432428 let len = streams. len ( ) ;
433429 match len {
434430 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 ( ) ) ) ) ) ,
436432 }
437433 }
438434 }
@@ -458,9 +454,9 @@ impl Cursor {
458454 }
459455
460456 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) => {
464460 if self . index < stream. len ( ) {
465461 self . index += 1 ;
466462 Some ( stream[ self . index - 1 ] . clone ( ) )
@@ -476,16 +472,15 @@ impl Cursor {
476472 return ;
477473 }
478474 let index = self . index ;
479- let stream = mem:: replace ( & mut self . stream , TokenStream :: Empty ) ;
475+ let stream = mem:: replace ( & mut self . stream , TokenStream ( None ) ) ;
480476 * self = TokenStream :: from_streams ( vec ! [ stream, new_stream] ) . into_trees ( ) ;
481477 self . index = index;
482478 }
483479
484480 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 ( ) ) ,
489484 }
490485 }
491486}
0 commit comments