@@ -145,24 +145,23 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
145
145
// start position, we ensure that any replace range which encloses
146
146
// another replace range will capture the *replaced* tokens for the inner
147
147
// 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 ( ) {
149
149
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 ( ) ) ;
162
150
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 ;
163
156
tokens. splice (
164
157
( 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
+ ) ,
166
165
) ;
167
166
}
168
167
make_attr_token_stream ( tokens. into_iter ( ) , self . break_last_token )
@@ -315,7 +314,7 @@ impl<'a> Parser<'a> {
315
314
. iter ( )
316
315
. cloned ( )
317
316
. 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 ) )
319
318
. collect ( )
320
319
} ;
321
320
@@ -345,17 +344,15 @@ impl<'a> Parser<'a> {
345
344
&& matches ! ( self . capture_state. capturing, Capturing :: Yes )
346
345
&& has_cfg_or_cfg_attr ( final_attrs)
347
346
{
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" ) ;
349
348
350
349
// 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
352
351
// that has `#[derive]`, then this will allow us to cfg-expand this
353
352
// AST node.
354
353
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) ) ) ;
359
356
self . capture_state . replace_ranges . extend ( inner_attr_replace_ranges) ;
360
357
}
361
358
0 commit comments