make EII iteration faster

This commit is contained in:
Jana Dönszelmann 2025-09-10 13:21:59 -07:00
parent 1cbdaf246b
commit b732030025
No known key found for this signature in database
6 changed files with 32 additions and 3 deletions

View file

@ -227,6 +227,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
vis_span,
span: self.lower_span(i.span),
has_delayed_lints: !self.delayed_lints.is_empty(),
eii: find_attr!(
attrs,
AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..)
),
};
self.arena.alloc(item)
}
@ -670,6 +674,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
vis_span,
span: this.lower_span(use_tree.span),
has_delayed_lints: !this.delayed_lints.is_empty(),
eii: find_attr!(
attrs,
AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..)
),
};
hir::OwnerNode::Item(this.arena.alloc(item))
});

View file

@ -4164,6 +4164,9 @@ pub struct Item<'hir> {
pub span: Span,
pub vis_span: Span,
pub has_delayed_lints: bool,
/// hint to speed up collection: true if the item is a static or function and has
/// either an `EiiImpls` or `EiiExternTarget` attribute
pub eii: bool,
}
impl<'hir> Item<'hir> {

View file

@ -532,7 +532,7 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) ->
}
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result {
let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _ } = item;
let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _, eii: _ } = item;
try_visit!(visitor.visit_id(item.hir_id()));
match *kind {
ItemKind::ExternCrate(orig_name, ident) => {

View file

@ -24,8 +24,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap
let mut eiis = EiiMap::default();
// iterate over all items in the current crate
// FIXME(speed up)
for id in tcx.hir_crate_items(()).definitions() {
for id in tcx.hir_crate_items(()).eiis() {
for i in
find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten()
{

View file

@ -1224,6 +1224,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
body_owners,
opaques,
nested_bodies,
eiis,
..
} = collector;
ModuleItems {
@ -1237,6 +1238,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
opaques: opaques.into_boxed_slice(),
nested_bodies: nested_bodies.into_boxed_slice(),
delayed_lint_items: Box::new([]),
eiis: eiis.into_boxed_slice(),
}
}
@ -1259,6 +1261,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
opaques,
nested_bodies,
mut delayed_lint_items,
eiis,
..
} = collector;
@ -1281,6 +1284,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
opaques: opaques.into_boxed_slice(),
nested_bodies: nested_bodies.into_boxed_slice(),
delayed_lint_items: delayed_lint_items.into_boxed_slice(),
eiis: eiis.into_boxed_slice(),
}
}
@ -1298,6 +1302,7 @@ struct ItemCollector<'tcx> {
opaques: Vec<LocalDefId>,
nested_bodies: Vec<LocalDefId>,
delayed_lint_items: Vec<OwnerId>,
eiis: Vec<LocalDefId>,
}
impl<'tcx> ItemCollector<'tcx> {
@ -1314,6 +1319,7 @@ impl<'tcx> ItemCollector<'tcx> {
opaques: Vec::default(),
nested_bodies: Vec::default(),
delayed_lint_items: Vec::default(),
eiis: Vec::default(),
}
}
}
@ -1335,6 +1341,12 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
self.delayed_lint_items.push(item.item_id().owner_id);
}
if let ItemKind::Static(..) | ItemKind::Fn { .. } | ItemKind::Macro(..) = &item.kind
&& item.eii
{
self.eiis.push(item.owner_id.def_id)
}
// Items that are modules are handled here instead of in visit_mod.
if let ItemKind::Mod(_, module) = &item.kind {
self.submodules.push(item.owner_id);

View file

@ -37,6 +37,9 @@ pub struct ModuleItems {
nested_bodies: Box<[LocalDefId]>,
// only filled with hir_crate_items, not with hir_module_items
delayed_lint_items: Box<[OwnerId]>,
/// Statics and functions with an `EiiImpls` or `EiiExternTarget` attribute
eiis: Box<[LocalDefId]>,
}
impl ModuleItems {
@ -58,6 +61,10 @@ impl ModuleItems {
self.delayed_lint_items.iter().copied()
}
pub fn eiis(&self) -> impl Iterator<Item = LocalDefId> {
self.eiis.iter().copied()
}
/// Returns all items that are associated with some `impl` block (both inherent and trait impl
/// blocks).
pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {