@@ -136,17 +136,30 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
136136 node_replacements. array_windows ( )
137137 {
138138 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: ({:?}, {:?}) ({:?}, {:?})" ,
141142 node_range,
142143 tokens,
143144 next_node_range,
144145 next_tokens,
145146 ) ;
146147 }
147148
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 ( ) {
150163 assert ! (
151164 !node_range. 0 . is_empty( ) ,
152165 "Cannot replace an empty node range: {:?}" ,
@@ -383,9 +396,10 @@ impl<'a> Parser<'a> {
383396 // from `ParserRange` form to `NodeRange` form. We will perform the actual
384397 // replacement only when we convert the `LazyAttrTokenStream` to an
385398 // `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 ( )
389403 . chain ( inner_attr_parser_replacements)
390404 . map ( |( parser_range, data) | {
391405 ( NodeRange :: new ( parser_range, collect_pos. start_pos ) , data)
0 commit comments