]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/item_scope.rs
Replaced fold with for loop
[rust.git] / crates / hir_def / src / item_scope.rs
index 0a2a6719edc1951f96aa037e62be965687633275..258d1e0f6c5191a5c17cd97b5d3ef3ef31943344 100644 (file)
@@ -8,7 +8,7 @@
 use once_cell::sync::Lazy;
 use profile::Count;
 use rustc_hash::{FxHashMap, FxHashSet};
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 use stdx::format_to;
 use syntax::ast;
 
@@ -44,6 +44,8 @@ pub struct ItemScope {
     /// The defs declared in this scope. Each def has a single scope where it is
     /// declared.
     declarations: Vec<ModuleDefId>,
+    macro_declarations: Vec<MacroDefId>,
+
     impls: Vec<ImplId>,
     unnamed_consts: Vec<ConstId>,
     /// Traits imported via `use Trait as _;`.
@@ -62,7 +64,10 @@ pub struct ItemScope {
     // be all resolved to the last one defined if shadowing happens.
     legacy_macros: FxHashMap<Name, MacroDefId>,
     attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
-    derive_macros: FxHashMap<AstId<ast::Item>, SmallVec<[(AttrId, MacroCallId); 1]>>,
+    /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
+    /// paired with the derive macro invocations for the specific attribute.
+    derive_macros:
+        FxHashMap<AstId<ast::Adt>, SmallVec<[(AttrId, SmallVec<[Option<MacroCallId>; 1]>); 1]>>,
 }
 
 pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
@@ -101,6 +106,10 @@ pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
         self.declarations.iter().copied()
     }
 
+    pub fn macro_declarations(&self) -> impl Iterator<Item = MacroDefId> + '_ {
+        self.macro_declarations.iter().copied()
+    }
+
     pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
         self.impls.iter().copied()
     }
@@ -163,6 +172,10 @@ pub(crate) fn declare(&mut self, def: ModuleDefId) {
         self.declarations.push(def)
     }
 
+    pub(crate) fn declare_macro(&mut self, def: MacroDefId) {
+        self.macro_declarations.push(def);
+    }
+
     pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
         self.legacy_macros.get(name).copied()
     }
@@ -189,19 +202,40 @@ pub(crate) fn attr_macro_invocs(
         self.attr_macros.iter().map(|(k, v)| (*k, *v))
     }
 
-    pub(crate) fn add_derive_macro_invoc(
+    pub(crate) fn set_derive_macro_invoc(
         &mut self,
-        item: AstId<ast::Item>,
+        adt: AstId<ast::Adt>,
         call: MacroCallId,
         attr_id: AttrId,
+        idx: usize,
+    ) {
+        if let Some(derives) = self.derive_macros.get_mut(&adt) {
+            if let Some((_, invocs)) = derives.iter_mut().find(|&&mut (id, _)| id == attr_id) {
+                invocs[idx] = Some(call);
+            }
+        }
+    }
+
+    /// We are required to set this up front as derive invocation recording happens out of order
+    /// due to the fixed pointer iteration loop being able to record some derives later than others
+    /// independent of their indices.
+    pub(crate) fn init_derive_attribute(
+        &mut self,
+        adt: AstId<ast::Adt>,
+        attr_id: AttrId,
+        len: usize,
     ) {
-        self.derive_macros.entry(item).or_default().push((attr_id, call));
+        self.derive_macros.entry(adt).or_default().push((attr_id, smallvec![None; len]));
     }
 
     pub(crate) fn derive_macro_invocs(
         &self,
-    ) -> impl Iterator<Item = (AstId<ast::Item>, &[(AttrId, MacroCallId)])> + '_ {
-        self.derive_macros.iter().map(|(k, v)| (*k, v.as_ref()))
+    ) -> impl Iterator<
+        Item = (AstId<ast::Adt>, impl Iterator<Item = (AttrId, &[Option<MacroCallId>])>),
+    > + '_ {
+        self.derive_macros
+            .iter()
+            .map(|(k, v)| (*k, v.iter().map(|(attr_id, invocs)| (*attr_id, &**invocs))))
     }
 
     pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
@@ -336,7 +370,8 @@ pub(crate) fn shrink_to_fit(&mut self) {
             values,
             macros,
             unresolved,
-            declarations: defs,
+            declarations,
+            macro_declarations,
             impls,
             unnamed_consts,
             unnamed_trait_imports,
@@ -348,7 +383,8 @@ pub(crate) fn shrink_to_fit(&mut self) {
         values.shrink_to_fit();
         macros.shrink_to_fit();
         unresolved.shrink_to_fit();
-        defs.shrink_to_fit();
+        declarations.shrink_to_fit();
+        macro_declarations.shrink_to_fit();
         impls.shrink_to_fit();
         unnamed_consts.shrink_to_fit();
         unnamed_trait_imports.shrink_to_fit();