Auto merge of #142455 - jdonszelmann:attempt-to-mitigate-delayed-lint-perf-problems, r=oli-obk
collect delayed lints in hir_crate_items r? `@oli-obk` Attempt to mitigate perf problems in rust-lang/rust#138164
This commit is contained in:
commit
586ad391f5
6 changed files with 81 additions and 9 deletions
|
|
@ -145,6 +145,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind,
|
kind,
|
||||||
vis_span,
|
vis_span,
|
||||||
span: self.lower_span(i.span),
|
span: self.lower_span(i.span),
|
||||||
|
has_delayed_lints: !self.delayed_lints.is_empty(),
|
||||||
};
|
};
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
|
|
@ -599,6 +600,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind,
|
kind,
|
||||||
vis_span,
|
vis_span,
|
||||||
span: this.lower_span(use_tree.span),
|
span: this.lower_span(use_tree.span),
|
||||||
|
has_delayed_lints: !this.delayed_lints.is_empty(),
|
||||||
};
|
};
|
||||||
hir::OwnerNode::Item(this.arena.alloc(item))
|
hir::OwnerNode::Item(this.arena.alloc(item))
|
||||||
});
|
});
|
||||||
|
|
@ -697,6 +699,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind,
|
kind,
|
||||||
vis_span: self.lower_span(i.vis.span),
|
vis_span: self.lower_span(i.vis.span),
|
||||||
span: self.lower_span(i.span),
|
span: self.lower_span(i.span),
|
||||||
|
has_delayed_lints: !self.delayed_lints.is_empty(),
|
||||||
};
|
};
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
|
|
@ -941,6 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
kind,
|
kind,
|
||||||
span: self.lower_span(i.span),
|
span: self.lower_span(i.span),
|
||||||
defaultness: hir::Defaultness::Default { has_value: has_default },
|
defaultness: hir::Defaultness::Default { has_value: has_default },
|
||||||
|
has_delayed_lints: !self.delayed_lints.is_empty(),
|
||||||
};
|
};
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
|
|
@ -1100,6 +1104,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
vis_span: self.lower_span(i.vis.span),
|
vis_span: self.lower_span(i.vis.span),
|
||||||
span: self.lower_span(i.span),
|
span: self.lower_span(i.span),
|
||||||
defaultness,
|
defaultness,
|
||||||
|
has_delayed_lints: !self.delayed_lints.is_empty(),
|
||||||
};
|
};
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3064,6 +3064,7 @@ pub struct TraitItem<'hir> {
|
||||||
pub kind: TraitItemKind<'hir>,
|
pub kind: TraitItemKind<'hir>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub defaultness: Defaultness,
|
pub defaultness: Defaultness,
|
||||||
|
pub has_delayed_lints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! expect_methods_self_kind {
|
macro_rules! expect_methods_self_kind {
|
||||||
|
|
@ -3168,6 +3169,7 @@ pub struct ImplItem<'hir> {
|
||||||
pub defaultness: Defaultness,
|
pub defaultness: Defaultness,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub vis_span: Span,
|
pub vis_span: Span,
|
||||||
|
pub has_delayed_lints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir> ImplItem<'hir> {
|
impl<'hir> ImplItem<'hir> {
|
||||||
|
|
@ -4087,6 +4089,7 @@ pub struct Item<'hir> {
|
||||||
pub kind: ItemKind<'hir>,
|
pub kind: ItemKind<'hir>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub vis_span: Span,
|
pub vis_span: Span,
|
||||||
|
pub has_delayed_lints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir> Item<'hir> {
|
impl<'hir> Item<'hir> {
|
||||||
|
|
@ -4492,6 +4495,7 @@ pub struct ForeignItem<'hir> {
|
||||||
pub owner_id: OwnerId,
|
pub owner_id: OwnerId,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub vis_span: Span,
|
pub vis_span: Span,
|
||||||
|
pub has_delayed_lints: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForeignItem<'_> {
|
impl ForeignItem<'_> {
|
||||||
|
|
@ -4974,7 +4978,7 @@ mod size_asserts {
|
||||||
static_assert_size!(Expr<'_>, 64);
|
static_assert_size!(Expr<'_>, 64);
|
||||||
static_assert_size!(ExprKind<'_>, 48);
|
static_assert_size!(ExprKind<'_>, 48);
|
||||||
static_assert_size!(FnDecl<'_>, 40);
|
static_assert_size!(FnDecl<'_>, 40);
|
||||||
static_assert_size!(ForeignItem<'_>, 88);
|
static_assert_size!(ForeignItem<'_>, 96);
|
||||||
static_assert_size!(ForeignItemKind<'_>, 56);
|
static_assert_size!(ForeignItemKind<'_>, 56);
|
||||||
static_assert_size!(GenericArg<'_>, 16);
|
static_assert_size!(GenericArg<'_>, 16);
|
||||||
static_assert_size!(GenericBound<'_>, 64);
|
static_assert_size!(GenericBound<'_>, 64);
|
||||||
|
|
|
||||||
|
|
@ -537,7 +537,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 {
|
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: _ } = item;
|
let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _ } = item;
|
||||||
try_visit!(visitor.visit_id(item.hir_id()));
|
try_visit!(visitor.visit_id(item.hir_id()));
|
||||||
match *kind {
|
match *kind {
|
||||||
ItemKind::ExternCrate(orig_name, ident) => {
|
ItemKind::ExternCrate(orig_name, ident) => {
|
||||||
|
|
@ -656,7 +656,8 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
foreign_item: &'v ForeignItem<'v>,
|
foreign_item: &'v ForeignItem<'v>,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
let ForeignItem { ident, kind, owner_id: _, span: _, vis_span: _ } = foreign_item;
|
let ForeignItem { ident, kind, owner_id: _, span: _, vis_span: _, has_delayed_lints: _ } =
|
||||||
|
foreign_item;
|
||||||
try_visit!(visitor.visit_id(foreign_item.hir_id()));
|
try_visit!(visitor.visit_id(foreign_item.hir_id()));
|
||||||
try_visit!(visitor.visit_ident(*ident));
|
try_visit!(visitor.visit_ident(*ident));
|
||||||
|
|
||||||
|
|
@ -1205,7 +1206,15 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
trait_item: &'v TraitItem<'v>,
|
trait_item: &'v TraitItem<'v>,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
|
let TraitItem {
|
||||||
|
ident,
|
||||||
|
generics,
|
||||||
|
ref defaultness,
|
||||||
|
ref kind,
|
||||||
|
span,
|
||||||
|
owner_id: _,
|
||||||
|
has_delayed_lints: _,
|
||||||
|
} = *trait_item;
|
||||||
let hir_id = trait_item.hir_id();
|
let hir_id = trait_item.hir_id();
|
||||||
try_visit!(visitor.visit_ident(ident));
|
try_visit!(visitor.visit_ident(ident));
|
||||||
try_visit!(visitor.visit_generics(&generics));
|
try_visit!(visitor.visit_generics(&generics));
|
||||||
|
|
@ -1261,6 +1270,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
|
||||||
ref defaultness,
|
ref defaultness,
|
||||||
span: _,
|
span: _,
|
||||||
vis_span: _,
|
vis_span: _,
|
||||||
|
has_delayed_lints: _,
|
||||||
} = *impl_item;
|
} = *impl_item;
|
||||||
|
|
||||||
try_visit!(visitor.visit_ident(ident));
|
try_visit!(visitor.visit_ident(ident));
|
||||||
|
|
|
||||||
|
|
@ -193,13 +193,41 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
||||||
let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
|
let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tcx.sess.time("emit_ast_lowering_delayed_lints", || {
|
||||||
|
// sanity check in debug mode that all lints are really noticed
|
||||||
|
// and we really will emit them all in the loop right below.
|
||||||
|
//
|
||||||
|
// during ast lowering, when creating items, foreign items, trait items and impl items
|
||||||
|
// we store in them whether they have any lints in their owner node that should be
|
||||||
|
// picked up by `hir_crate_items`. However, theoretically code can run between that
|
||||||
|
// boolean being inserted into the item and the owner node being created.
|
||||||
|
// We don't want any new lints to be emitted there
|
||||||
|
// (though honestly, you have to really try to manage to do that but still),
|
||||||
|
// but this check is there to catch that.
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
// iterate over all owners
|
||||||
for owner_id in tcx.hir_crate_items(()).owners() {
|
for owner_id in tcx.hir_crate_items(()).owners() {
|
||||||
|
// if it has delayed lints
|
||||||
|
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
|
||||||
|
if !delayed_lints.lints.is_empty() {
|
||||||
|
// assert that delayed_lint_items also picked up this item to have lints
|
||||||
|
assert!(
|
||||||
|
tcx.hir_crate_items(()).delayed_lint_items().any(|i| i == owner_id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
|
||||||
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
|
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
|
||||||
for lint in &delayed_lints.lints {
|
for lint in &delayed_lints.lints {
|
||||||
emit_delayed_lint(lint, tcx);
|
emit_delayed_lint(lint, tcx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
tcx.par_hir_body_owners(|item_def_id| {
|
tcx.par_hir_body_owners(|item_def_id| {
|
||||||
let def_kind = tcx.def_kind(item_def_id);
|
let def_kind = tcx.def_kind(item_def_id);
|
||||||
|
|
|
||||||
|
|
@ -1233,6 +1233,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
|
||||||
body_owners: body_owners.into_boxed_slice(),
|
body_owners: body_owners.into_boxed_slice(),
|
||||||
opaques: opaques.into_boxed_slice(),
|
opaques: opaques.into_boxed_slice(),
|
||||||
nested_bodies: nested_bodies.into_boxed_slice(),
|
nested_bodies: nested_bodies.into_boxed_slice(),
|
||||||
|
delayed_lint_items: Box::new([]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1254,6 +1255,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
||||||
body_owners,
|
body_owners,
|
||||||
opaques,
|
opaques,
|
||||||
nested_bodies,
|
nested_bodies,
|
||||||
|
delayed_lint_items,
|
||||||
..
|
..
|
||||||
} = collector;
|
} = collector;
|
||||||
|
|
||||||
|
|
@ -1266,6 +1268,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
||||||
body_owners: body_owners.into_boxed_slice(),
|
body_owners: body_owners.into_boxed_slice(),
|
||||||
opaques: opaques.into_boxed_slice(),
|
opaques: opaques.into_boxed_slice(),
|
||||||
nested_bodies: nested_bodies.into_boxed_slice(),
|
nested_bodies: nested_bodies.into_boxed_slice(),
|
||||||
|
delayed_lint_items: delayed_lint_items.into_boxed_slice(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1282,6 +1285,7 @@ struct ItemCollector<'tcx> {
|
||||||
body_owners: Vec<LocalDefId>,
|
body_owners: Vec<LocalDefId>,
|
||||||
opaques: Vec<LocalDefId>,
|
opaques: Vec<LocalDefId>,
|
||||||
nested_bodies: Vec<LocalDefId>,
|
nested_bodies: Vec<LocalDefId>,
|
||||||
|
delayed_lint_items: Vec<OwnerId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ItemCollector<'tcx> {
|
impl<'tcx> ItemCollector<'tcx> {
|
||||||
|
|
@ -1297,6 +1301,7 @@ impl<'tcx> ItemCollector<'tcx> {
|
||||||
body_owners: Vec::default(),
|
body_owners: Vec::default(),
|
||||||
opaques: Vec::default(),
|
opaques: Vec::default(),
|
||||||
nested_bodies: Vec::default(),
|
nested_bodies: Vec::default(),
|
||||||
|
delayed_lint_items: Vec::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1314,6 +1319,9 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.items.push(item.item_id());
|
self.items.push(item.item_id());
|
||||||
|
if self.crate_collector && item.has_delayed_lints {
|
||||||
|
self.delayed_lint_items.push(item.item_id().owner_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Items that are modules are handled here instead of in visit_mod.
|
// Items that are modules are handled here instead of in visit_mod.
|
||||||
if let ItemKind::Mod(_, module) = &item.kind {
|
if let ItemKind::Mod(_, module) = &item.kind {
|
||||||
|
|
@ -1329,6 +1337,9 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
|
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
|
||||||
self.foreign_items.push(item.foreign_item_id());
|
self.foreign_items.push(item.foreign_item_id());
|
||||||
|
if self.crate_collector && item.has_delayed_lints {
|
||||||
|
self.delayed_lint_items.push(item.foreign_item_id().owner_id);
|
||||||
|
}
|
||||||
intravisit::walk_foreign_item(self, item)
|
intravisit::walk_foreign_item(self, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1362,6 +1373,10 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.trait_items.push(item.trait_item_id());
|
self.trait_items.push(item.trait_item_id());
|
||||||
|
if self.crate_collector && item.has_delayed_lints {
|
||||||
|
self.delayed_lint_items.push(item.trait_item_id().owner_id);
|
||||||
|
}
|
||||||
|
|
||||||
intravisit::walk_trait_item(self, item)
|
intravisit::walk_trait_item(self, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1371,6 +1386,10 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.impl_items.push(item.impl_item_id());
|
self.impl_items.push(item.impl_item_id());
|
||||||
|
if self.crate_collector && item.has_delayed_lints {
|
||||||
|
self.delayed_lint_items.push(item.impl_item_id().owner_id);
|
||||||
|
}
|
||||||
|
|
||||||
intravisit::walk_impl_item(self, item)
|
intravisit::walk_impl_item(self, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ pub struct ModuleItems {
|
||||||
opaques: Box<[LocalDefId]>,
|
opaques: Box<[LocalDefId]>,
|
||||||
body_owners: Box<[LocalDefId]>,
|
body_owners: Box<[LocalDefId]>,
|
||||||
nested_bodies: Box<[LocalDefId]>,
|
nested_bodies: Box<[LocalDefId]>,
|
||||||
|
// only filled with hir_crate_items, not with hir_module_items
|
||||||
|
delayed_lint_items: Box<[OwnerId]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleItems {
|
impl ModuleItems {
|
||||||
|
|
@ -49,6 +51,10 @@ impl ModuleItems {
|
||||||
self.trait_items.iter().copied()
|
self.trait_items.iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delayed_lint_items(&self) -> impl Iterator<Item = OwnerId> {
|
||||||
|
self.delayed_lint_items.iter().copied()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns all items that are associated with some `impl` block (both inherent and trait impl
|
/// Returns all items that are associated with some `impl` block (both inherent and trait impl
|
||||||
/// blocks).
|
/// blocks).
|
||||||
pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
|
pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue