@@ -145,24 +145,23 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
145145 // start position, we ensure that any replace range which encloses
146146 // another replace range will capture the *replaced* tokens for the inner
147147 // range, not the original tokens.
148- for ( range, new_tokens ) in replace_ranges. into_iter ( ) . rev ( ) {
148+ for ( range, attr_data ) in replace_ranges. into_iter ( ) . rev ( ) {
149149 assert ! ( !range. is_empty( ) , "Cannot replace an empty range: {range:?}" ) ;
150- // Replace ranges are only allowed to decrease the number of tokens.
151- assert ! (
152- range. len( ) >= new_tokens. len( ) ,
153- "Range {range:?} has greater len than {new_tokens:?}"
154- ) ;
155-
156- // Replace any removed tokens with `FlatToken::Empty`.
157- // This keeps the total length of `tokens` constant throughout the
158- // replacement process, allowing us to use all of the `ReplaceRanges` entries
159- // without adjusting indices.
160- let filler = iter:: repeat ( ( FlatToken :: Empty , Spacing :: Alone ) )
161- . take ( range. len ( ) - new_tokens. len ( ) ) ;
162150
151+ // Replace the tokens in range with zero or one `FlatToken::AttrTarget`s, plus
152+ // enough `FlatToken::Empty`s to fill up the rest of the range. This keeps the
153+ // total length of `tokens` constant throughout the replacement process, allowing
154+ // us to use all of the `ReplaceRanges` entries without adjusting indices.
155+ let attr_data_len = attr_data. is_some ( ) as usize ;
163156 tokens. splice (
164157 ( range. start as usize ) ..( range. end as usize ) ,
165- new_tokens. into_iter ( ) . chain ( filler) ,
158+ attr_data
159+ . into_iter ( )
160+ . map ( |attr_data| ( FlatToken :: AttrTarget ( attr_data) , Spacing :: Alone ) )
161+ . chain (
162+ iter:: repeat ( ( FlatToken :: Empty , Spacing :: Alone ) )
163+ . take ( range. len ( ) - attr_data_len) ,
164+ ) ,
166165 ) ;
167166 }
168167 make_attr_token_stream ( tokens. into_iter ( ) , self . break_last_token )
@@ -315,7 +314,7 @@ impl<'a> Parser<'a> {
315314 . iter ( )
316315 . cloned ( )
317316 . chain ( inner_attr_replace_ranges. iter ( ) . cloned ( ) )
318- . map ( |( range, tokens ) | ( ( range. start - start_pos) ..( range. end - start_pos) , tokens ) )
317+ . map ( |( range, data ) | ( ( range. start - start_pos) ..( range. end - start_pos) , data ) )
319318 . collect ( )
320319 } ;
321320
@@ -345,17 +344,15 @@ impl<'a> Parser<'a> {
345344 && matches ! ( self . capture_state. capturing, Capturing :: Yes )
346345 && has_cfg_or_cfg_attr ( final_attrs)
347346 {
348- let attr_data = AttributesData { attrs : final_attrs . iter ( ) . cloned ( ) . collect ( ) , tokens } ;
347+ assert ! ( ! self . break_last_token , "Should not have unglued last token with cfg attr" ) ;
349348
350349 // Replace the entire AST node that we just parsed, including attributes,
351- // with a `FlatToken::AttrTarget `. If this AST node is inside an item
350+ // with `attr_data `. If this AST node is inside an item
352351 // that has `#[derive]`, then this will allow us to cfg-expand this
353352 // AST node.
354353 let start_pos = if has_outer_attrs { attrs. start_pos } else { start_pos } ;
355- let new_tokens = vec ! [ ( FlatToken :: AttrTarget ( attr_data) , Spacing :: Alone ) ] ;
356-
357- assert ! ( !self . break_last_token, "Should not have unglued last token with cfg attr" ) ;
358- self . capture_state . replace_ranges . push ( ( start_pos..end_pos, new_tokens) ) ;
354+ let attr_data = AttributesData { attrs : final_attrs. iter ( ) . cloned ( ) . collect ( ) , tokens } ;
355+ self . capture_state . replace_ranges . push ( ( start_pos..end_pos, Some ( attr_data) ) ) ;
359356 self . capture_state . replace_ranges . extend ( inner_attr_replace_ranges) ;
360357 }
361358
0 commit comments