]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/data.rs
Merge #11284
[rust.git] / crates / hir_def / src / data.rs
index f08be39128a31874d1ada3bd11da5108b99a7857..97930871f0d90b6845b66976e70e7af2e3f04def 100644 (file)
@@ -184,6 +184,7 @@ pub struct TraitData {
     /// method calls to this trait's methods when the receiver is an array and the crate edition is
     /// 2015 or 2018.
     pub skip_array_during_method_dispatch: bool,
+    // box it as the vec is usually empty anyways
     pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
 }
 
@@ -208,17 +209,8 @@ pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitDa
             .by_key("rustc_skip_array_during_method_dispatch")
             .exists();
 
-        let (attribute_calls, items) = collect_items(
-            db,
-            module_id,
-            &mut expander,
-            tr_def.items.iter().copied(),
-            tr_loc.id.tree_id(),
-            container,
-            100,
-        );
-        let attribute_calls =
-            if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
+        let (items, attribute_calls) =
+            do_collect(db, module_id, &mut expander, &tr_def.items, tr_loc.id.tree_id(), container);
 
         Arc::new(TraitData {
             name,
@@ -263,6 +255,7 @@ pub struct ImplData {
     pub self_ty: Interned<TypeRef>,
     pub items: Vec<AssocItemId>,
     pub is_negative: bool,
+    // box it as the vec is usually empty anyways
     pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
 }
 
@@ -280,18 +273,15 @@ pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc<ImplData>
         let container = ItemContainerId::ImplId(id);
         let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
 
-        let (attribute_calls, items) = collect_items(
+        let (items, attribute_calls) = do_collect(
             db,
             module_id,
             &mut expander,
-            impl_def.items.iter().copied(),
+            &impl_def.items,
             impl_loc.id.tree_id(),
             container,
-            100,
         );
         let items = items.into_iter().map(|(_, item)| item).collect();
-        let attribute_calls =
-            if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
 
         Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls })
     }
@@ -348,44 +338,64 @@ pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<St
     }
 }
 
+fn do_collect(
+    db: &dyn DefDatabase,
+    module_id: ModuleId,
+    expander: &mut Expander,
+    assoc_items: &[AssocItem],
+    tree_id: item_tree::TreeId,
+    container: ItemContainerId,
+) -> (Vec<(Name, AssocItemId)>, Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>) {
+    let mut items = Vec::new();
+    let mut attribute_calls = Vec::new();
+
+    collect_items(
+        db,
+        &mut items,
+        &mut attribute_calls,
+        module_id,
+        expander,
+        assoc_items.iter().copied(),
+        tree_id,
+        container,
+    );
+
+    let attribute_calls =
+        if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
+    (items, attribute_calls)
+}
+
 fn collect_items(
     db: &dyn DefDatabase,
+    items: &mut Vec<(Name, AssocItemId)>,
+    attr_calls: &mut Vec<(AstId<ast::Item>, MacroCallId)>,
     module: ModuleId,
     expander: &mut Expander,
     assoc_items: impl Iterator<Item = AssocItem>,
     tree_id: item_tree::TreeId,
     container: ItemContainerId,
-    limit: usize,
-) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
-    if limit == 0 {
-        return Default::default();
-    }
-
+) {
     let item_tree = tree_id.item_tree(db);
     let crate_graph = db.crate_graph();
     let cfg_options = &crate_graph[module.krate].cfg_options;
     let def_map = module.def_map(db);
 
-    let mut items = Vec::new();
-    let mut attribute_calls = Vec::new();
-
     'items: for item in assoc_items {
         let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into());
         if !attrs.is_cfg_enabled(cfg_options) {
             continue;
         }
+
         for attr in &*attrs {
             let ast_id = AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast());
             let ast_id_with_path = AstIdWithPath { path: (*attr.path).clone(), ast_id };
+
             if let Ok(ResolvedAttr::Macro(call_id)) =
                 def_map.resolve_attr_macro(db, module.local_id, ast_id_with_path, attr)
             {
-                attribute_calls.push((ast_id, call_id));
+                attr_calls.push((ast_id, call_id));
                 let res = expander.enter_expand_id(db, call_id);
-                let (mac_attrs, mac_items) =
-                    collect_macro_items(db, module, expander, container, limit, res);
-                items.extend(mac_items);
-                attribute_calls.extend(mac_attrs);
+                collect_macro_items(db, items, attr_calls, module, expander, container, res);
                 continue 'items;
             }
         }
@@ -419,37 +429,29 @@ fn collect_items(
                 let res = expander.enter_expand(db, call);
 
                 if let Ok(res) = res {
-                    let (mac_attrs, mac_items) =
-                        collect_macro_items(db, module, expander, container, limit, res);
-                    items.extend(mac_items);
-                    attribute_calls.extend(mac_attrs);
+                    collect_macro_items(db, items, attr_calls, module, expander, container, res);
                 }
             }
         }
     }
-
-    (attribute_calls, items)
 }
 
 fn collect_macro_items(
     db: &dyn DefDatabase,
+    items: &mut Vec<(Name, AssocItemId)>,
+    attr_calls: &mut Vec<(AstId<ast::Item>, MacroCallId)>,
     module: ModuleId,
     expander: &mut Expander,
     container: ItemContainerId,
-    limit: usize,
     res: ExpandResult<Option<(Mark, ast::MacroItems)>>,
-) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
+) {
     if let Some((mark, mac)) = res.value {
         let src: InFile<ast::MacroItems> = expander.to_source(mac);
         let tree_id = item_tree::TreeId::new(src.file_id, None);
         let item_tree = tree_id.item_tree(db);
         let iter = item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
-        let items = collect_items(db, module, expander, iter, tree_id, container, limit - 1);
+        collect_items(db, items, attr_calls, module, expander, iter, tree_id, container);
 
         expander.exit(db, mark);
-
-        return items;
     }
-
-    Default::default()
 }