@@ -233,14 +233,90 @@ impl From<TokenTree> for TokenStream {
233233 }
234234}
235235
236+ /// Non-generic helper for implementing `FromIterator<TokenTree>` and
237+ /// `Extend<TokenTree>` with less monomorphization in calling crates.
238+ struct ExtendStreamWithTreesHelper {
239+ trees : Vec <
240+ bridge:: TokenTree <
241+ bridge:: client:: Group ,
242+ bridge:: client:: Punct ,
243+ bridge:: client:: Ident ,
244+ bridge:: client:: Literal ,
245+ > ,
246+ > ,
247+ }
248+
249+ impl ExtendStreamWithTreesHelper {
250+ fn new ( capacity : usize ) -> Self {
251+ ExtendStreamWithTreesHelper { trees : Vec :: with_capacity ( capacity) }
252+ }
253+
254+ fn push ( & mut self , tree : TokenTree ) {
255+ self . trees . push ( tree_to_bridge_tree ( tree) ) ;
256+ }
257+
258+ fn build ( self ) -> TokenStream {
259+ if self . trees . is_empty ( ) {
260+ TokenStream ( None )
261+ } else {
262+ TokenStream ( Some ( bridge:: client:: TokenStream :: concat_trees ( None , self . trees ) ) )
263+ }
264+ }
265+
266+ fn extend ( self , stream : & mut TokenStream ) {
267+ if self . trees . is_empty ( ) {
268+ return ;
269+ }
270+ stream. 0 = Some ( bridge:: client:: TokenStream :: concat_trees ( stream. 0 . take ( ) , self . trees ) )
271+ }
272+ }
273+
274+ /// Non-generic helper for implementing `FromIterator<TokenStream>` and
275+ /// `Extend<TokenStream>` with less monomorphization in calling crates.
276+ struct ExtendStreamWithStreamsHelper {
277+ streams : Vec < bridge:: client:: TokenStream > ,
278+ }
279+
280+ impl ExtendStreamWithStreamsHelper {
281+ fn new ( capacity : usize ) -> Self {
282+ ExtendStreamWithStreamsHelper { streams : Vec :: with_capacity ( capacity) }
283+ }
284+
285+ fn push ( & mut self , stream : TokenStream ) {
286+ if let Some ( stream) = stream. 0 {
287+ self . streams . push ( stream) ;
288+ }
289+ }
290+
291+ fn build ( mut self ) -> TokenStream {
292+ if self . streams . len ( ) <= 1 {
293+ TokenStream ( self . streams . pop ( ) )
294+ } else {
295+ TokenStream ( Some ( bridge:: client:: TokenStream :: concat_streams ( None , self . streams ) ) )
296+ }
297+ }
298+
299+ fn extend ( mut self , stream : & mut TokenStream ) {
300+ if self . streams . is_empty ( ) {
301+ return ;
302+ }
303+ let base = stream. 0 . take ( ) ;
304+ if base. is_none ( ) && self . streams . len ( ) == 1 {
305+ stream. 0 = self . streams . pop ( ) ;
306+ } else {
307+ stream. 0 = Some ( bridge:: client:: TokenStream :: concat_streams ( base, self . streams ) ) ;
308+ }
309+ }
310+ }
311+
236312/// Collects a number of token trees into a single stream.
237313#[ stable( feature = "proc_macro_lib2" , since = "1.29.0" ) ]
238314impl iter:: FromIterator < TokenTree > for TokenStream {
239315 fn from_iter < I : IntoIterator < Item = TokenTree > > ( trees : I ) -> Self {
240- TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees (
241- None ,
242- trees . into_iter ( ) . map ( tree_to_bridge_tree ) . collect ( ) ,
243- ) ) )
316+ let iter = trees . into_iter ( ) ;
317+ let mut builder = ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ;
318+ iter . for_each ( |tree| builder . push ( tree ) ) ;
319+ builder . build ( )
244320 }
245321}
246322
@@ -249,30 +325,30 @@ impl iter::FromIterator<TokenTree> for TokenStream {
249325#[ stable( feature = "proc_macro_lib" , since = "1.15.0" ) ]
250326impl iter:: FromIterator < TokenStream > for TokenStream {
251327 fn from_iter < I : IntoIterator < Item = TokenStream > > ( streams : I ) -> Self {
252- TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams (
253- None ,
254- streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) ,
255- ) ) )
328+ let iter = streams . into_iter ( ) ;
329+ let mut builder = ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ;
330+ iter . for_each ( |stream| builder . push ( stream ) ) ;
331+ builder . build ( )
256332 }
257333}
258334
259335#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
260336impl Extend < TokenTree > for TokenStream {
261337 fn extend < I : IntoIterator < Item = TokenTree > > ( & mut self , trees : I ) {
262- * self = TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees (
263- self . 0 . take ( ) ,
264- trees . into_iter ( ) . map ( |tree| tree_to_bridge_tree ( tree) ) . collect ( ) ,
265- ) ) ) ;
338+ let iter = trees . into_iter ( ) ;
339+ let mut builder = ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ;
340+ iter . for_each ( |tree| builder . push ( tree) ) ;
341+ builder . extend ( self ) ;
266342 }
267343}
268344
269345#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
270346impl Extend < TokenStream > for TokenStream {
271347 fn extend < I : IntoIterator < Item = TokenStream > > ( & mut self , streams : I ) {
272- * self = TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams (
273- self . 0 . take ( ) ,
274- streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) ,
275- ) ) ) ;
348+ let iter = streams . into_iter ( ) ;
349+ let mut builder = ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ;
350+ iter . for_each ( |stream| builder . push ( stream ) ) ;
351+ builder . extend ( self ) ;
276352 }
277353}
278354
0 commit comments