@@ -229,14 +229,89 @@ impl From<TokenTree> for TokenStream {
229
229
}
230
230
}
231
231
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
+
232
307
/// Collects a number of token trees into a single stream.
233
308
#[ stable( feature = "proc_macro_lib2" , since = "1.29.0" ) ]
234
309
impl iter:: FromIterator < TokenTree > for TokenStream {
235
310
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 ( )
240
315
}
241
316
}
242
317
@@ -245,30 +320,30 @@ impl iter::FromIterator<TokenTree> for TokenStream {
245
320
#[ stable( feature = "proc_macro_lib" , since = "1.15.0" ) ]
246
321
impl iter:: FromIterator < TokenStream > for TokenStream {
247
322
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 ( )
252
327
}
253
328
}
254
329
255
330
#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
256
331
impl Extend < TokenTree > for TokenStream {
257
332
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 ) ;
262
337
}
263
338
}
264
339
265
340
#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
266
341
impl Extend < TokenStream > for TokenStream {
267
342
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 ) ;
272
347
}
273
348
}
274
349
0 commit comments