Skip to content

Commit 8d4f40e

Browse files
committed
Do less allocs in trait_data and impl_data queries
1 parent 6746ba5 commit 8d4f40e

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

crates/hir_def/src/data.rs

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ pub struct TraitData {
184184
/// method calls to this trait's methods when the receiver is an array and the crate edition is
185185
/// 2015 or 2018.
186186
pub skip_array_during_method_dispatch: bool,
187+
// box it as the vec is usually empty anyways
187188
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
188189
}
189190

@@ -208,17 +209,8 @@ impl TraitData {
208209
.by_key("rustc_skip_array_during_method_dispatch")
209210
.exists();
210211

211-
let (attribute_calls, items) = collect_items(
212-
db,
213-
module_id,
214-
&mut expander,
215-
tr_def.items.iter().copied(),
216-
tr_loc.id.tree_id(),
217-
container,
218-
100,
219-
);
220-
let attribute_calls =
221-
if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
212+
let (items, attribute_calls) =
213+
do_collect(db, module_id, &mut expander, &tr_def.items, tr_loc.id.tree_id(), container);
222214

223215
Arc::new(TraitData {
224216
name,
@@ -263,6 +255,7 @@ pub struct ImplData {
263255
pub self_ty: Interned<TypeRef>,
264256
pub items: Vec<AssocItemId>,
265257
pub is_negative: bool,
258+
// box it as the vec is usually empty anyways
266259
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
267260
}
268261

@@ -280,18 +273,15 @@ impl ImplData {
280273
let container = ItemContainerId::ImplId(id);
281274
let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
282275

283-
let (attribute_calls, items) = collect_items(
276+
let (items, attribute_calls) = do_collect(
284277
db,
285278
module_id,
286279
&mut expander,
287-
impl_def.items.iter().copied(),
280+
&impl_def.items,
288281
impl_loc.id.tree_id(),
289282
container,
290-
100,
291283
);
292284
let items = items.into_iter().map(|(_, item)| item).collect();
293-
let attribute_calls =
294-
if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
295285

296286
Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls })
297287
}
@@ -348,44 +338,70 @@ impl StaticData {
348338
}
349339
}
350340

341+
fn do_collect(
342+
db: &dyn DefDatabase,
343+
module_id: ModuleId,
344+
expander: &mut Expander,
345+
assoc_items: &[AssocItem],
346+
tree_id: item_tree::TreeId,
347+
container: ItemContainerId,
348+
) -> (Vec<(Name, AssocItemId)>, Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>) {
349+
let mut items = Vec::new();
350+
let mut attribute_calls = Vec::new();
351+
352+
collect_items(
353+
db,
354+
&mut items,
355+
&mut attribute_calls,
356+
module_id,
357+
expander,
358+
assoc_items.iter().copied(),
359+
tree_id,
360+
container,
361+
100,
362+
);
363+
364+
let attribute_calls =
365+
if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
366+
(items, attribute_calls)
367+
}
368+
351369
fn collect_items(
352370
db: &dyn DefDatabase,
371+
items: &mut Vec<(Name, AssocItemId)>,
372+
attr_calls: &mut Vec<(AstId<ast::Item>, MacroCallId)>,
353373
module: ModuleId,
354374
expander: &mut Expander,
355375
assoc_items: impl Iterator<Item = AssocItem>,
356376
tree_id: item_tree::TreeId,
357377
container: ItemContainerId,
358378
limit: usize,
359-
) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
379+
) {
360380
if limit == 0 {
361-
return Default::default();
381+
return;
362382
}
363383

364384
let item_tree = tree_id.item_tree(db);
365385
let crate_graph = db.crate_graph();
366386
let cfg_options = &crate_graph[module.krate].cfg_options;
367387
let def_map = module.def_map(db);
368388

369-
let mut items = Vec::new();
370-
let mut attribute_calls = Vec::new();
371-
372389
'items: for item in assoc_items {
373390
let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into());
374391
if !attrs.is_cfg_enabled(cfg_options) {
375392
continue;
376393
}
394+
377395
for attr in &*attrs {
378396
let ast_id = AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast());
379397
let ast_id_with_path = AstIdWithPath { path: (*attr.path).clone(), ast_id };
398+
380399
if let Ok(ResolvedAttr::Macro(call_id)) =
381400
def_map.resolve_attr_macro(db, module.local_id, ast_id_with_path, attr)
382401
{
383-
attribute_calls.push((ast_id, call_id));
402+
attr_calls.push((ast_id, call_id));
384403
let res = expander.enter_expand_id(db, call_id);
385-
let (mac_attrs, mac_items) =
386-
collect_macro_items(db, module, expander, container, limit, res);
387-
items.extend(mac_items);
388-
attribute_calls.extend(mac_attrs);
404+
collect_macro_items(db, items, attr_calls, module, expander, container, limit, res);
389405
continue 'items;
390406
}
391407
}
@@ -419,37 +435,32 @@ fn collect_items(
419435
let res = expander.enter_expand(db, call);
420436

421437
if let Ok(res) = res {
422-
let (mac_attrs, mac_items) =
423-
collect_macro_items(db, module, expander, container, limit, res);
424-
items.extend(mac_items);
425-
attribute_calls.extend(mac_attrs);
438+
collect_macro_items(
439+
db, items, attr_calls, module, expander, container, limit, res,
440+
);
426441
}
427442
}
428443
}
429444
}
430-
431-
(attribute_calls, items)
432445
}
433446

434447
fn collect_macro_items(
435448
db: &dyn DefDatabase,
449+
items: &mut Vec<(Name, AssocItemId)>,
450+
attr_calls: &mut Vec<(AstId<ast::Item>, MacroCallId)>,
436451
module: ModuleId,
437452
expander: &mut Expander,
438453
container: ItemContainerId,
439454
limit: usize,
440455
res: ExpandResult<Option<(Mark, ast::MacroItems)>>,
441-
) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
456+
) {
442457
if let Some((mark, mac)) = res.value {
443458
let src: InFile<ast::MacroItems> = expander.to_source(mac);
444459
let tree_id = item_tree::TreeId::new(src.file_id, None);
445460
let item_tree = tree_id.item_tree(db);
446461
let iter = item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
447-
let items = collect_items(db, module, expander, iter, tree_id, container, limit - 1);
462+
collect_items(db, items, attr_calls, module, expander, iter, tree_id, container, limit - 1);
448463

449464
expander.exit(db, mark);
450-
451-
return items;
452465
}
453-
454-
Default::default()
455466
}

0 commit comments

Comments
 (0)