about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-05 05:53:19 +0000
committerbors <bors@rust-lang.org>2024-11-05 05:53:19 +0000
commit27e38f8fc7efc57b75e9a763d7a0ee44822cd5f7 (patch)
tree756365d8392283d39747d565efb5d95387c77242 /compiler/rustc_parse/src/parser
parent96477c55bcfa7121470ed225f602c1c639aeaa18 (diff)
parent7bff6ff3a6bfd0caa14bef3c440977669db92a82 (diff)
downloadrust-27e38f8fc7efc57b75e9a763d7a0ee44822cd5f7.tar.gz
rust-27e38f8fc7efc57b75e9a763d7a0ee44822cd5f7.zip
Auto merge of #132626 - workingjubilee:rollup-hbmtbzk, r=workingjubilee
Rollup of 11 pull requests

Successful merges:

 - #131153 (Improve duplicate derive Copy/Clone diagnostics)
 - #132025 (fix suggestion for diagnostic error E0027)
 - #132303 (More tests for non-exhaustive C-like enums in FFI)
 - #132492 (remove support for extern-block const intrinsics)
 - #132587 (Revert "Avoid nested replacement ranges" from #129346.)
 - #132596 ([rustdoc] Fix `--show-coverage` when JSON output format is used)
 - #132598 (Clippy: Move some attribute lints to be early pass (post expansion))
 - #132601 (Update books)
 - #132606 (Improve example of `impl Pattern for &[char]`)
 - #132608 (document `type_implements_trait`)
 - #132609 (docs: fix grammar in doc comment at unix/process.rs)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs28
1 files changed, 21 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 8bd615e6d79..c85d0bd05cb 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -136,8 +136,9 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
                 node_replacements.array_windows()
             {
                 assert!(
-                    node_range.0.end <= next_node_range.0.start,
-                    "Node ranges should be disjoint: ({:?}, {:?}) ({:?}, {:?})",
+                    node_range.0.end <= next_node_range.0.start
+                        || node_range.0.end >= next_node_range.0.end,
+                    "Node ranges should be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})",
                     node_range,
                     tokens,
                     next_node_range,
@@ -145,8 +146,20 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
                 );
             }
 
-            // Process the replace ranges.
-            for (node_range, target) in node_replacements.into_iter() {
+            // Process the replace ranges, starting from the highest start
+            // position and working our way back. If have tokens like:
+            //
+            // `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
+            //
+            // Then we will generate replace ranges for both
+            // the `#[cfg(FALSE)] field: bool` and the entire
+            // `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
+            //
+            // By starting processing from the replace range with the greatest
+            // start position, we ensure that any (outer) replace range which
+            // encloses another (inner) replace range will fully overwrite the
+            // inner range's replacement.
+            for (node_range, target) in node_replacements.into_iter().rev() {
                 assert!(
                     !node_range.0.is_empty(),
                     "Cannot replace an empty node range: {:?}",
@@ -383,9 +396,10 @@ impl<'a> Parser<'a> {
             // from `ParserRange` form to `NodeRange` form. We will perform the actual
             // replacement only when we convert the `LazyAttrTokenStream` to an
             // `AttrTokenStream`.
-            self.capture_state
-                .parser_replacements
-                .drain(parser_replacements_start..parser_replacements_end)
+            self.capture_state.parser_replacements
+                [parser_replacements_start..parser_replacements_end]
+                .iter()
+                .cloned()
                 .chain(inner_attr_parser_replacements)
                 .map(|(parser_range, data)| {
                     (NodeRange::new(parser_range, collect_pos.start_pos), data)