about summary refs log tree commit diff
path: root/compiler/rustc_span/src/hygiene.rs
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2025-03-15 02:54:53 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2025-03-15 20:45:56 +0300
commit07328d5d408f707f92c4208cb5d4042af981ff43 (patch)
tree0f7072af168ebc01104a679919e485eb7b507967 /compiler/rustc_span/src/hygiene.rs
parent6e1effe948525538427b2a6932f1619d74776cef (diff)
downloadrust-07328d5d408f707f92c4208cb5d4042af981ff43.tar.gz
rust-07328d5d408f707f92c4208cb5d4042af981ff43.zip
hygiene: Update `$crate` pretty-printing to account for holes in syntax contexts
Diffstat (limited to 'compiler/rustc_span/src/hygiene.rs')
-rw-r--r--compiler/rustc_span/src/hygiene.rs29
1 files changed, 15 insertions, 14 deletions
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 36ecbe1cb78..4390085cd04 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -653,25 +653,26 @@ pub fn walk_chain_collapsed(span: Span, to: Span) -> Span {
 
 pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symbol) {
     // The new contexts that need updating are at the end of the list and have `$crate` as a name.
-    let (len, to_update) = HygieneData::with(|data| {
-        (
-            data.syntax_context_data.len(),
-            data.syntax_context_data
-                .iter()
-                .rev()
-                .take_while(|scdata| scdata.dollar_crate_name == kw::DollarCrate)
-                .count(),
-        )
+    // Also decoding placeholders can be encountered among both old and new contexts.
+    let mut to_update = vec![];
+    HygieneData::with(|data| {
+        for (idx, scdata) in data.syntax_context_data.iter().enumerate().rev() {
+            if scdata.dollar_crate_name == kw::DollarCrate {
+                to_update.push((idx, kw::DollarCrate));
+            } else if !scdata.is_decode_placeholder() {
+                break;
+            }
+        }
     });
     // The callback must be called from outside of the `HygieneData` lock,
     // since it will try to acquire it too.
-    let range_to_update = len - to_update..len;
-    let names: Vec<_> =
-        range_to_update.clone().map(|idx| get_name(SyntaxContext::from_u32(idx as u32))).collect();
+    for (idx, name) in &mut to_update {
+        *name = get_name(SyntaxContext::from_usize(*idx));
+    }
     HygieneData::with(|data| {
-        range_to_update.zip(names).for_each(|(idx, name)| {
+        for (idx, name) in to_update {
             data.syntax_context_data[idx].dollar_crate_name = name;
-        })
+        }
     })
 }