diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0e0ded0b27a0..a68d63bf1464 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -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)) }); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f5470adb87e0..c60471848c89 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 625766f8bd3d..be3cab6461ef 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -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) => { diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 2d99ba516ad4..5558ff930851 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -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() { diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index bf3192d9df17..5da762ef8565 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -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, nested_bodies: Vec, delayed_lint_items: Vec, + eiis: Vec, } 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); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0ab5a792e040..217ecbab059e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -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 { + 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 {