Merge pull request #19985 from ChayimFriedman2/proc-macro-srv-ast-id

fix: Support spans with proc macro servers from before the ast id changes
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 7452381..2a87b15 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -20,12 +20,10 @@
 use triomphe::Arc;
 use vfs::{AbsPathBuf, AnchoredPath, FileId, VfsPath, file_set::FileSet};
 
-use crate::{CrateWorkspaceData, EditionedFileId, RootQueryDb};
+use crate::{CrateWorkspaceData, EditionedFileId, FxIndexSet, RootQueryDb};
 
 pub type ProcMacroPaths = FxHashMap<CrateBuilderId, Result<(String, AbsPathBuf), String>>;
 
-type FxIndexSet<T> = indexmap::IndexSet<T, FxBuildHasher>;
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct SourceRootId(pub u32);
 
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 4d4e6ca..478fae6 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -28,6 +28,8 @@
 use triomphe::Arc;
 pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet};
 
+pub type FxIndexSet<T> = indexmap::IndexSet<T, rustc_hash::FxBuildHasher>;
+
 #[macro_export]
 macro_rules! impl_intern_key {
     ($id:ident, $loc:ident) => {
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs
index 89eeaf0..4ba31c1 100644
--- a/crates/hir-def/src/expr_store/lower.rs
+++ b/crates/hir-def/src/expr_store/lower.rs
@@ -7,6 +7,7 @@
 
 use std::mem;
 
+use base_db::FxIndexSet;
 use cfg::CfgOptions;
 use either::Either;
 use hir_expand::{
@@ -66,8 +67,6 @@
 
 pub use self::path::hir_segment_to_ast_segment;
 
-type FxIndexSet<K> = indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
-
 pub(super) fn lower_body(
     db: &dyn DefDatabase,
     owner: DefWithBodyId,
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 07d1500..81c8f56 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -246,7 +246,7 @@
                 macro_calls,
                 macro_rules,
                 macro_defs,
-                vis,
+                vis: _,
             } = &mut **data;
 
             uses.shrink_to_fit();
@@ -266,36 +266,13 @@
             macro_calls.shrink_to_fit();
             macro_rules.shrink_to_fit();
             macro_defs.shrink_to_fit();
-
-            vis.arena.shrink_to_fit();
         }
     }
 }
 
 #[derive(Default, Debug, Eq, PartialEq)]
 struct ItemVisibilities {
-    arena: Arena<RawVisibility>,
-}
-
-impl ItemVisibilities {
-    fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId {
-        match &vis {
-            RawVisibility::Public => RawVisibilityId::PUB,
-            RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
-                match (path.kind, explicitiy) {
-                    (PathKind::SELF, VisibilityExplicitness::Explicit) => {
-                        RawVisibilityId::PRIV_EXPLICIT
-                    }
-                    (PathKind::SELF, VisibilityExplicitness::Implicit) => {
-                        RawVisibilityId::PRIV_IMPLICIT
-                    }
-                    (PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
-                    _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
-                }
-            }
-            _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
-        }
-    }
+    arena: Box<[RawVisibility]>,
 }
 
 #[derive(Default, Debug, Eq, PartialEq)]
@@ -577,7 +554,7 @@
                     VisibilityExplicitness::Explicit,
                 )
             }),
-            _ => &self.data().vis.arena[Idx::from_raw(index.0.into())],
+            _ => &self.data().vis.arena[index.0 as usize],
         }
     }
 }
@@ -702,7 +679,7 @@
 }
 
 /// Visibility of an item, not yet resolved.
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum RawVisibility {
     /// `pub(in module)`, `pub(crate)` or `pub(super)`. Also private, which is
     /// equivalent to `pub(self)`.
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index d9588cb..26d209c 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -2,6 +2,7 @@
 
 use std::{cell::OnceCell, collections::hash_map::Entry};
 
+use base_db::FxIndexSet;
 use hir_expand::{
     HirFileId,
     mod_path::PathKind,
@@ -37,6 +38,7 @@
     source_ast_id_map: Arc<AstIdMap>,
     span_map: OnceCell<SpanMap>,
     file: HirFileId,
+    visibilities: FxIndexSet<RawVisibility>,
 }
 
 impl<'a> Ctx<'a> {
@@ -47,6 +49,7 @@
             source_ast_id_map: db.ast_id_map(file),
             file,
             span_map: OnceCell::new(),
+            visibilities: FxIndexSet::default(),
         }
     }
 
@@ -57,6 +60,9 @@
     pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree {
         self.tree.top_level =
             item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
+        if let Some(data) = &mut self.tree.data {
+            data.vis.arena = self.visibilities.into_iter().collect();
+        }
         self.tree
     }
 
@@ -90,6 +96,9 @@
             }
         }
 
+        if let Some(data) = &mut self.tree.data {
+            data.vis.arena = self.visibilities.into_iter().collect();
+        }
         self.tree
     }
 
@@ -115,7 +124,9 @@
                 }
             }
         }
-
+        if let Some(data) = &mut self.tree.data {
+            data.vis.arena = self.visibilities.into_iter().collect();
+        }
         self.tree
     }
 
@@ -370,7 +381,22 @@
         let vis = visibility_from_ast(self.db, item.visibility(), &mut |range| {
             self.span_map().span_for_range(range).ctx
         });
-        self.data().vis.alloc(vis)
+        match &vis {
+            RawVisibility::Public => RawVisibilityId::PUB,
+            RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
+                match (path.kind, explicitiy) {
+                    (PathKind::SELF, VisibilityExplicitness::Explicit) => {
+                        RawVisibilityId::PRIV_EXPLICIT
+                    }
+                    (PathKind::SELF, VisibilityExplicitness::Implicit) => {
+                        RawVisibilityId::PRIV_IMPLICIT
+                    }
+                    (PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
+                    _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
+                }
+            }
+            _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
+        }
     }
 }
 
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index dc4334e..b532156 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -14,7 +14,7 @@
 mod mbe;
 mod proc_macros;
 
-use std::{iter, ops::Range, sync};
+use std::{any::TypeId, iter, ops::Range, sync};
 
 use base_db::RootQueryDb;
 use expect_test::Expect;
@@ -380,4 +380,8 @@
             panic!("got invalid macro input: {:?}", parse.errors());
         }
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
diff --git a/crates/hir-expand/src/proc_macro.rs b/crates/hir-expand/src/proc_macro.rs
index 1cd975b..1c8ebb6 100644
--- a/crates/hir-expand/src/proc_macro.rs
+++ b/crates/hir-expand/src/proc_macro.rs
@@ -34,9 +34,7 @@
         current_dir: String,
     ) -> Result<tt::TopSubtree, ProcMacroExpansionError>;
 
-    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
-        other.type_id() == self.type_id()
-    }
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool;
 }
 
 impl PartialEq for dyn ProcMacroExpander {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 47607a5..1049895 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -244,7 +244,7 @@
         offset: TextSize,
     ) -> impl Iterator<Item = ast::NameLike> + 'slf {
         node.token_at_offset(offset)
-            .map(move |token| self.descend_into_macros_no_opaque(token))
+            .map(move |token| self.descend_into_macros_no_opaque(token, true))
             .map(|descendants| descendants.into_iter().filter_map(move |it| it.value.parent()))
             // re-order the tokens from token_at_offset by returning the ancestors with the smaller first nodes first
             // See algo::ancestors_at_offset, which uses the same approach
@@ -1009,10 +1009,11 @@
     pub fn descend_into_macros_no_opaque(
         &self,
         token: SyntaxToken,
+        always_descend_into_derives: bool,
     ) -> SmallVec<[InFile<SyntaxToken>; 1]> {
         let mut res = smallvec![];
         let token = self.wrap_token_infile(token);
-        self.descend_into_macros_all(token.clone(), true, &mut |t, ctx| {
+        self.descend_into_macros_all(token.clone(), always_descend_into_derives, &mut |t, ctx| {
             if !ctx.is_opaque(self.db) {
                 // Don't descend into opaque contexts
                 res.push(t);
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index e87ab87..a0815c3 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -1,5 +1,6 @@
 //! File symbol extraction.
 
+use base_db::FxIndexSet;
 use either::Either;
 use hir_def::{
     AdtId, AssocItemId, Complete, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId,
@@ -21,8 +22,6 @@
 
 use crate::{HasCrate, Module, ModuleDef, Semantics};
 
-pub type FxIndexSet<T> = indexmap::IndexSet<T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
-
 /// The actual data that is stored in the index. It should be as compact as
 /// possible.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/crates/ide/src/goto_declaration.rs b/crates/ide/src/goto_declaration.rs
index 38c032d..267e8ff 100644
--- a/crates/ide/src/goto_declaration.rs
+++ b/crates/ide/src/goto_declaration.rs
@@ -29,7 +29,7 @@
         .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate] | T![Self]))?;
     let range = original_token.text_range();
     let info: Vec<NavigationTarget> = sema
-        .descend_into_macros_no_opaque(original_token)
+        .descend_into_macros_no_opaque(original_token, false)
         .iter()
         .filter_map(|token| {
             let parent = token.value.parent()?;
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 7917aab..574803f 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -88,7 +88,7 @@
     }
 
     let navs = sema
-        .descend_into_macros_no_opaque(original_token.clone())
+        .descend_into_macros_no_opaque(original_token.clone(), false)
         .into_iter()
         .filter_map(|token| {
             let parent = token.value.parent()?;
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs
index a6c7ea2..9781e71 100644
--- a/crates/ide/src/goto_type_definition.rs
+++ b/crates/ide/src/goto_type_definition.rs
@@ -70,7 +70,7 @@
     }
 
     let range = token.text_range();
-    sema.descend_into_macros_no_opaque(token)
+    sema.descend_into_macros_no_opaque(token,false)
         .into_iter()
         .filter_map(|token| {
             sema
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index ab13960..f48150b 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -5,11 +5,11 @@
 use cfg::{CfgAtom, CfgExpr};
 use hir::{
     AsAssocItem, AttrsWithOwner, HasAttrs, HasCrate, HasSource, ModPath, Name, PathKind, Semantics,
-    Symbol, db::HirDatabase, sym, symbols::FxIndexSet,
+    Symbol, db::HirDatabase, sym,
 };
 use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn};
 use ide_db::{
-    FilePosition, FxHashMap, FxIndexMap, RootDatabase, SymbolKind,
+    FilePosition, FxHashMap, FxIndexMap, FxIndexSet, RootDatabase, SymbolKind,
     base_db::RootQueryDb,
     defs::Definition,
     documentation::docs_from_attrs,
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs
index 30e2d54..89b8631 100644
--- a/crates/load-cargo/src/lib.rs
+++ b/crates/load-cargo/src/lib.rs
@@ -2,7 +2,7 @@
 //! for incorporating changes.
 // Note, don't remove any public api from this. This API is consumed by external tools
 // to run rust-analyzer as a library.
-use std::{collections::hash_map::Entry, mem, path::Path, sync};
+use std::{any::Any, collections::hash_map::Entry, mem, path::Path, sync};
 
 use crossbeam_channel::{Receiver, unbounded};
 use hir_expand::proc_macro::{
@@ -512,6 +512,10 @@
             Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),
         }
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        (other as &dyn Any).downcast_ref::<Self>() == Some(self)
+    }
 }
 
 #[cfg(test)]
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs
index 8eb48f8..8937e53 100644
--- a/crates/test-fixture/src/lib.rs
+++ b/crates/test-fixture/src/lib.rs
@@ -1,5 +1,5 @@
 //! A set of high-level utility fixture methods to use in tests.
-use std::{mem, str::FromStr, sync};
+use std::{any::TypeId, mem, str::FromStr, sync};
 
 use base_db::{
     Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData,
@@ -677,6 +677,10 @@
     ) -> Result<TopSubtree, ProcMacroExpansionError> {
         Ok(subtree.clone())
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Expands to a macro_rules! macro, for issue #18089.
@@ -708,6 +712,10 @@
             #subtree
         })
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Pastes the attribute input as its output
@@ -728,6 +736,10 @@
             .cloned()
             .ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into()))
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 #[derive(Debug)]
@@ -759,6 +771,10 @@
         top_subtree_delimiter_mut.close = def_site;
         Ok(result)
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 #[derive(Debug)]
@@ -790,6 +806,10 @@
         traverse(&mut builder, input.iter());
         Ok(builder.build())
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Replaces every literal with an empty string literal and every identifier with its first letter,
@@ -830,6 +850,10 @@
             }
         }
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Reads ident type within string quotes, for issue #17479.
@@ -855,6 +879,10 @@
             #symbol()
         })
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Reads ident type within string quotes, for issue #17479.
@@ -906,6 +934,10 @@
             }
         })
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Reads ident type within string quotes, for issue #17479.
@@ -933,6 +965,10 @@
         }
         Ok(subtree.clone())
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }
 
 // Generates a new type by adding a suffix to the original name
@@ -987,4 +1023,8 @@
 
         Ok(ret)
     }
+
+    fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
+        other.type_id() == TypeId::of::<Self>()
+    }
 }