@@ -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