about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-07 14:21:26 +0000
committerbors <bors@rust-lang.org>2024-03-07 14:21:26 +0000
commitb1f6d56e44c1ce67b5e723776e948c5c82f794d4 (patch)
tree2d4400353fe2edcda1c451ab7090ef67aeb0cf46
parente101f24798b4779a05a3b4fb9904264d97bd7740 (diff)
parent09b9a921a851d729f14e74ca8b3540d6b407886d (diff)
downloadrust-b1f6d56e44c1ce67b5e723776e948c5c82f794d4.tar.gz
rust-b1f6d56e44c1ce67b5e723776e948c5c82f794d4.zip
Auto merge of #16777 - Veykril:body-invalid, r=Veykril
fix: Don't invalid body query results when generating desugared names

The hack remains until we get hygiene, but with this the generated names are stable across bodies
-rw-r--r--crates/hir-def/src/body/lower.rs9
-rw-r--r--crates/hir-expand/src/name.rs14
2 files changed, 10 insertions, 13 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 18a6c5c2cdc..66691277894 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -703,7 +703,8 @@ impl ExprCollector<'_> {
         let Some(try_from_output) = LangItem::TryTraitFromOutput.path(self.db, self.krate) else {
             return self.collect_block(e);
         };
-        let label = self.alloc_label_desugared(Label { name: Name::generate_new_name() });
+        let label = self
+            .alloc_label_desugared(Label { name: Name::generate_new_name(self.body.labels.len()) });
         let old_label = self.current_try_block_label.replace(label);
 
         let (btail, expr_id) = self.with_labeled_rib(label, |this| {
@@ -840,7 +841,7 @@ impl ExprCollector<'_> {
                 this.collect_expr_opt(e.loop_body().map(|it| it.into()))
             }),
         };
-        let iter_name = Name::generate_new_name();
+        let iter_name = Name::generate_new_name(self.body.exprs.len());
         let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr);
         let iter_expr_mut = self.alloc_expr(
             Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut },
@@ -901,7 +902,7 @@ impl ExprCollector<'_> {
             Expr::Call { callee: try_branch, args: Box::new([operand]), is_assignee_expr: false },
             syntax_ptr,
         );
-        let continue_name = Name::generate_new_name();
+        let continue_name = Name::generate_new_name(self.body.bindings.len());
         let continue_binding =
             self.alloc_binding(continue_name.clone(), BindingAnnotation::Unannotated);
         let continue_bpat =
@@ -916,7 +917,7 @@ impl ExprCollector<'_> {
             guard: None,
             expr: self.alloc_expr(Expr::Path(Path::from(continue_name)), syntax_ptr),
         };
-        let break_name = Name::generate_new_name();
+        let break_name = Name::generate_new_name(self.body.bindings.len());
         let break_binding = self.alloc_binding(break_name.clone(), BindingAnnotation::Unannotated);
         let break_bpat = self.alloc_pat_desugared(Pat::Bind { id: break_binding, subpat: None });
         self.add_definition_to_binding(break_binding, break_bpat);
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index cf17d90ed12..0b69799e6bf 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -111,15 +111,11 @@ impl Name {
         self == &Name::missing()
     }
 
-    /// Generates a new name which is only equal to itself, by incrementing a counter. Due
-    /// its implementation, it should not be used in things that salsa considers, like
-    /// type names or field names, and it should be only used in names of local variables
-    /// and labels and similar things.
-    pub fn generate_new_name() -> Name {
-        use std::sync::atomic::{AtomicUsize, Ordering};
-        static CNT: AtomicUsize = AtomicUsize::new(0);
-        let c = CNT.fetch_add(1, Ordering::Relaxed);
-        Name::new_text(format_smolstr!("<ra@gennew>{c}"))
+    /// Generates a new name that attempts to be unique. Should only be used when body lowering and
+    /// creating desugared locals and labels. The caller is responsible for picking an index
+    /// that is stable across re-executions
+    pub fn generate_new_name(idx: usize) -> Name {
+        Name::new_text(format_smolstr!("<ra@gennew>{idx}"))
     }
 
     /// Returns the tuple index this name represents if it is a tuple field.