@@ -136,17 +136,30 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
136
136
node_replacements. array_windows ( )
137
137
{
138
138
assert ! (
139
- node_range. 0 . end <= next_node_range. 0 . start,
140
- "Node ranges should be disjoint: ({:?}, {:?}) ({:?}, {:?})" ,
139
+ node_range. 0 . end <= next_node_range. 0 . start
140
+ || node_range. 0 . end >= next_node_range. 0 . end,
141
+ "Node ranges should be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})" ,
141
142
node_range,
142
143
tokens,
143
144
next_node_range,
144
145
next_tokens,
145
146
) ;
146
147
}
147
148
148
- // Process the replace ranges.
149
- for ( node_range, target) in node_replacements. into_iter ( ) {
149
+ // Process the replace ranges, starting from the highest start
150
+ // position and working our way back. If have tokens like:
151
+ //
152
+ // `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
153
+ //
154
+ // Then we will generate replace ranges for both
155
+ // the `#[cfg(FALSE)] field: bool` and the entire
156
+ // `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
157
+ //
158
+ // By starting processing from the replace range with the greatest
159
+ // start position, we ensure that any (outer) replace range which
160
+ // encloses another (inner) replace range will fully overwrite the
161
+ // inner range's replacement.
162
+ for ( node_range, target) in node_replacements. into_iter ( ) . rev ( ) {
150
163
assert ! (
151
164
!node_range. 0 . is_empty( ) ,
152
165
"Cannot replace an empty node range: {:?}" ,
@@ -383,9 +396,10 @@ impl<'a> Parser<'a> {
383
396
// from `ParserRange` form to `NodeRange` form. We will perform the actual
384
397
// replacement only when we convert the `LazyAttrTokenStream` to an
385
398
// `AttrTokenStream`.
386
- self . capture_state
387
- . parser_replacements
388
- . drain ( parser_replacements_start..parser_replacements_end)
399
+ self . capture_state . parser_replacements
400
+ [ parser_replacements_start..parser_replacements_end]
401
+ . iter ( )
402
+ . cloned ( )
389
403
. chain ( inner_attr_parser_replacements)
390
404
. map ( |( parser_range, data) | {
391
405
( NodeRange :: new ( parser_range, collect_pos. start_pos ) , data)
0 commit comments