@@ -229,14 +229,89 @@ impl From<TokenTree> for TokenStream {
229229    } 
230230} 
231231
232+ /// Non-generic helper for implementing `FromIterator<TokenTree>` and 
233+ /// `Extend<TokenTree>` with less monomorphization in calling crates. 
234+ struct  ExtendStreamWithTreesHelper  { 
235+     trees :  Vec < 
236+         bridge:: TokenTree < 
237+             bridge:: client:: TokenStream , 
238+             bridge:: client:: Span , 
239+             bridge:: client:: Symbol , 
240+         > , 
241+     > , 
242+ } 
243+ 
244+ impl  ExtendStreamWithTreesHelper  { 
245+     fn  new ( capacity :  usize )  -> Self  { 
246+         ExtendStreamWithTreesHelper  {  trees :  Vec :: with_capacity ( capacity)  } 
247+     } 
248+ 
249+     fn  push ( & mut  self ,  tree :  TokenTree )  { 
250+         self . trees . push ( tree_to_bridge_tree ( tree) ) ; 
251+     } 
252+ 
253+     fn  build ( self )  -> TokenStream  { 
254+         if  self . trees . is_empty ( )  { 
255+             TokenStream ( None ) 
256+         }  else  { 
257+             TokenStream ( Some ( bridge:: client:: TokenStream :: concat_trees ( None ,  self . trees ) ) ) 
258+         } 
259+     } 
260+ 
261+     fn  extend ( self ,  stream :  & mut  TokenStream )  { 
262+         if  self . trees . is_empty ( )  { 
263+             return ; 
264+         } 
265+         stream. 0  = Some ( bridge:: client:: TokenStream :: concat_trees ( stream. 0 . take ( ) ,  self . trees ) ) 
266+     } 
267+ } 
268+ 
269+ /// Non-generic helper for implementing `FromIterator<TokenStream>` and 
270+ /// `Extend<TokenStream>` with less monomorphization in calling crates. 
271+ struct  ExtendStreamWithStreamsHelper  { 
272+     streams :  Vec < bridge:: client:: TokenStream > , 
273+ } 
274+ 
275+ impl  ExtendStreamWithStreamsHelper  { 
276+     fn  new ( capacity :  usize )  -> Self  { 
277+         ExtendStreamWithStreamsHelper  {  streams :  Vec :: with_capacity ( capacity)  } 
278+     } 
279+ 
280+     fn  push ( & mut  self ,  stream :  TokenStream )  { 
281+         if  let  Some ( stream)  = stream. 0  { 
282+             self . streams . push ( stream) ; 
283+         } 
284+     } 
285+ 
286+     fn  build ( mut  self )  -> TokenStream  { 
287+         if  self . streams . len ( )  <= 1  { 
288+             TokenStream ( self . streams . pop ( ) ) 
289+         }  else  { 
290+             TokenStream ( Some ( bridge:: client:: TokenStream :: concat_streams ( None ,  self . streams ) ) ) 
291+         } 
292+     } 
293+ 
294+     fn  extend ( mut  self ,  stream :  & mut  TokenStream )  { 
295+         if  self . streams . is_empty ( )  { 
296+             return ; 
297+         } 
298+         let  base = stream. 0 . take ( ) ; 
299+         if  base. is_none ( )  && self . streams . len ( )  == 1  { 
300+             stream. 0  = self . streams . pop ( ) ; 
301+         }  else  { 
302+             stream. 0  = Some ( bridge:: client:: TokenStream :: concat_streams ( base,  self . streams ) ) ; 
303+         } 
304+     } 
305+ } 
306+ 
232307/// Collects a number of token trees into a single stream. 
233308#[ stable( feature = "proc_macro_lib2" ,  since = "1.29.0" ) ]  
234309impl  iter:: FromIterator < TokenTree >  for  TokenStream  { 
235310    fn  from_iter < I :  IntoIterator < Item  = TokenTree > > ( trees :  I )  -> Self  { 
236-         TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees ( 
237-              None , 
238-             trees . into_iter ( ) . map ( tree_to_bridge_tree ) . collect ( ) , 
239-         ) ) ) 
311+         let  iter = trees . into_iter ( ) ; 
312+         let   mut  builder =  ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ; 
313+         iter . for_each ( |tree| builder . push ( tree ) ) ; 
314+         builder . build ( ) 
240315    } 
241316} 
242317
@@ -245,30 +320,30 @@ impl iter::FromIterator<TokenTree> for TokenStream {
245320#[ stable( feature = "proc_macro_lib" ,  since = "1.15.0" ) ]  
246321impl  iter:: FromIterator < TokenStream >  for  TokenStream  { 
247322    fn  from_iter < I :  IntoIterator < Item  = TokenStream > > ( streams :  I )  -> Self  { 
248-         TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams ( 
249-              None , 
250-             streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) , 
251-         ) ) ) 
323+         let  iter = streams . into_iter ( ) ; 
324+         let   mut  builder =  ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ; 
325+         iter . for_each ( |stream| builder . push ( stream ) ) ; 
326+         builder . build ( ) 
252327    } 
253328} 
254329
255330#[ stable( feature = "token_stream_extend" ,  since = "1.30.0" ) ]  
256331impl  Extend < TokenTree >  for  TokenStream  { 
257332    fn  extend < I :  IntoIterator < Item  = TokenTree > > ( & mut  self ,  trees :  I )  { 
258-         * self  =  TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees ( 
259-              self . 0 . take ( ) , 
260-             trees . into_iter ( ) . map ( |tree| tree_to_bridge_tree ( tree) ) . collect ( ) , 
261-         ) ) ) ; 
333+         let  iter = trees . into_iter ( ) ; 
334+         let   mut  builder =  ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ; 
335+         iter . for_each ( |tree| builder . push ( tree) ) ; 
336+         builder . extend ( self ) ; 
262337    } 
263338} 
264339
265340#[ stable( feature = "token_stream_extend" ,  since = "1.30.0" ) ]  
266341impl  Extend < TokenStream >  for  TokenStream  { 
267342    fn  extend < I :  IntoIterator < Item  = TokenStream > > ( & mut  self ,  streams :  I )  { 
268-         * self  =  TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams ( 
269-              self . 0 . take ( ) , 
270-             streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) , 
271-         ) ) ) ; 
343+         let  iter = streams . into_iter ( ) ; 
344+         let   mut  builder =  ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ; 
345+         iter . for_each ( |stream| builder . push ( stream ) ) ; 
346+         builder . extend ( self ) ; 
272347    } 
273348} 
274349
0 commit comments