Skip to content

Commit 437cd00

Browse files
committed
Auto merge of #142455 - jdonszelmann:attempt-to-mitigate-delayed-lint-perf-problems, r=<try>
collect delayed lints in hir_crate_items r? `@oli-obk` Attempt to mitigate perf problems in #138164
2 parents 015c777 + 6f5a717 commit 437cd00

File tree

6 files changed

+81
-9
lines changed

6 files changed

+81
-9
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
145145
kind,
146146
vis_span,
147147
span: self.lower_span(i.span),
148+
has_delayed_lints: !self.delayed_lints.is_empty(),
148149
};
149150
self.arena.alloc(item)
150151
}
@@ -599,6 +600,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
599600
kind,
600601
vis_span,
601602
span: this.lower_span(use_tree.span),
603+
has_delayed_lints: !this.delayed_lints.is_empty(),
602604
};
603605
hir::OwnerNode::Item(this.arena.alloc(item))
604606
});
@@ -697,6 +699,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
697699
kind,
698700
vis_span: self.lower_span(i.vis.span),
699701
span: self.lower_span(i.span),
702+
has_delayed_lints: !self.delayed_lints.is_empty(),
700703
};
701704
self.arena.alloc(item)
702705
}
@@ -941,6 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
941944
kind,
942945
span: self.lower_span(i.span),
943946
defaultness: hir::Defaultness::Default { has_value: has_default },
947+
has_delayed_lints: !self.delayed_lints.is_empty(),
944948
};
945949
self.arena.alloc(item)
946950
}
@@ -1100,6 +1104,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11001104
vis_span: self.lower_span(i.vis.span),
11011105
span: self.lower_span(i.span),
11021106
defaultness,
1107+
has_delayed_lints: !self.delayed_lints.is_empty(),
11031108
};
11041109
self.arena.alloc(item)
11051110
}

compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3064,6 +3064,7 @@ pub struct TraitItem<'hir> {
30643064
pub kind: TraitItemKind<'hir>,
30653065
pub span: Span,
30663066
pub defaultness: Defaultness,
3067+
pub has_delayed_lints: bool,
30673068
}
30683069

30693070
macro_rules! expect_methods_self_kind {
@@ -3168,6 +3169,7 @@ pub struct ImplItem<'hir> {
31683169
pub defaultness: Defaultness,
31693170
pub span: Span,
31703171
pub vis_span: Span,
3172+
pub has_delayed_lints: bool,
31713173
}
31723174

31733175
impl<'hir> ImplItem<'hir> {
@@ -4087,6 +4089,7 @@ pub struct Item<'hir> {
40874089
pub kind: ItemKind<'hir>,
40884090
pub span: Span,
40894091
pub vis_span: Span,
4092+
pub has_delayed_lints: bool,
40904093
}
40914094

40924095
impl<'hir> Item<'hir> {
@@ -4492,6 +4495,7 @@ pub struct ForeignItem<'hir> {
44924495
pub owner_id: OwnerId,
44934496
pub span: Span,
44944497
pub vis_span: Span,
4498+
pub has_delayed_lints: bool,
44954499
}
44964500

44974501
impl ForeignItem<'_> {
@@ -4974,7 +4978,7 @@ mod size_asserts {
49744978
static_assert_size!(Expr<'_>, 64);
49754979
static_assert_size!(ExprKind<'_>, 48);
49764980
static_assert_size!(FnDecl<'_>, 40);
4977-
static_assert_size!(ForeignItem<'_>, 88);
4981+
static_assert_size!(ForeignItem<'_>, 96);
49784982
static_assert_size!(ForeignItemKind<'_>, 56);
49794983
static_assert_size!(GenericArg<'_>, 16);
49804984
static_assert_size!(GenericBound<'_>, 64);

compiler/rustc_hir/src/intravisit.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) ->
537537
}
538538

539539
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result {
540-
let Item { owner_id: _, kind, span: _, vis_span: _ } = item;
540+
let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _ } = item;
541541
try_visit!(visitor.visit_id(item.hir_id()));
542542
match *kind {
543543
ItemKind::ExternCrate(orig_name, ident) => {
@@ -656,7 +656,8 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
656656
visitor: &mut V,
657657
foreign_item: &'v ForeignItem<'v>,
658658
) -> V::Result {
659-
let ForeignItem { ident, kind, owner_id: _, span: _, vis_span: _ } = foreign_item;
659+
let ForeignItem { ident, kind, owner_id: _, span: _, vis_span: _, has_delayed_lints: _ } =
660+
foreign_item;
660661
try_visit!(visitor.visit_id(foreign_item.hir_id()));
661662
try_visit!(visitor.visit_ident(*ident));
662663

@@ -1205,7 +1206,15 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
12051206
visitor: &mut V,
12061207
trait_item: &'v TraitItem<'v>,
12071208
) -> V::Result {
1208-
let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
1209+
let TraitItem {
1210+
ident,
1211+
generics,
1212+
ref defaultness,
1213+
ref kind,
1214+
span,
1215+
owner_id: _,
1216+
has_delayed_lints: _,
1217+
} = *trait_item;
12091218
let hir_id = trait_item.hir_id();
12101219
try_visit!(visitor.visit_ident(ident));
12111220
try_visit!(visitor.visit_generics(&generics));
@@ -1261,6 +1270,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
12611270
ref defaultness,
12621271
span: _,
12631272
vis_span: _,
1273+
has_delayed_lints: _,
12641274
} = *impl_item;
12651275

12661276
try_visit!(visitor.visit_ident(ident));

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,41 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
201201
let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
202202
});
203203

204-
for owner_id in tcx.hir_crate_items(()).owners() {
205-
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
206-
for lint in &delayed_lints.lints {
207-
emit_delayed_lint(lint, tcx);
204+
tcx.sess.time("emit_ast_lowering_delayed_lints", || {
205+
// sanity check in debug mode that all lints are really noticed
206+
// and we really will emit them all in the loop right below.
207+
//
208+
// during ast lowering, when creating items, foreign items, trait items and impl items
209+
// we store in them whether they have any lints in their owner node that should be
210+
// picked up by `hir_crate_items`. However, theoretically code can run between that
211+
// boolean being inserted into the item and the owner node being created.
212+
// We don't want any new lints to be emitted there
213+
// (though honestly, you have to really try to manage to do that but still),
214+
// but this check is there to catch that.
215+
#[cfg(debug_assertions)]
216+
{
217+
// iterate over all owners
218+
for owner_id in tcx.hir_crate_items(()).owners() {
219+
// if it has delayed lints
220+
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
221+
if !delayed_lints.lints.is_empty() {
222+
// assert that delayed_lint_items also picked up this item to have lints
223+
assert!(
224+
tcx.hir_crate_items(()).delayed_lint_items().any(|i| i == owner_id)
225+
);
226+
}
227+
}
208228
}
209229
}
210-
}
230+
231+
for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
232+
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
233+
for lint in &delayed_lints.lints {
234+
emit_delayed_lint(lint, tcx);
235+
}
236+
}
237+
}
238+
});
211239

212240
tcx.par_hir_body_owners(|item_def_id| {
213241
let def_kind = tcx.def_kind(item_def_id);

compiler/rustc_middle/src/hir/map.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
12331233
body_owners: body_owners.into_boxed_slice(),
12341234
opaques: opaques.into_boxed_slice(),
12351235
nested_bodies: nested_bodies.into_boxed_slice(),
1236+
delayed_lint_items: Box::new([]),
12361237
}
12371238
}
12381239

@@ -1254,6 +1255,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
12541255
body_owners,
12551256
opaques,
12561257
nested_bodies,
1258+
delayed_lint_items,
12571259
..
12581260
} = collector;
12591261

@@ -1266,6 +1268,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
12661268
body_owners: body_owners.into_boxed_slice(),
12671269
opaques: opaques.into_boxed_slice(),
12681270
nested_bodies: nested_bodies.into_boxed_slice(),
1271+
delayed_lint_items: delayed_lint_items.into_boxed_slice(),
12691272
}
12701273
}
12711274

@@ -1282,6 +1285,7 @@ struct ItemCollector<'tcx> {
12821285
body_owners: Vec<LocalDefId>,
12831286
opaques: Vec<LocalDefId>,
12841287
nested_bodies: Vec<LocalDefId>,
1288+
delayed_lint_items: Vec<OwnerId>,
12851289
}
12861290

12871291
impl<'tcx> ItemCollector<'tcx> {
@@ -1297,6 +1301,7 @@ impl<'tcx> ItemCollector<'tcx> {
12971301
body_owners: Vec::default(),
12981302
opaques: Vec::default(),
12991303
nested_bodies: Vec::default(),
1304+
delayed_lint_items: Vec::default(),
13001305
}
13011306
}
13021307
}
@@ -1314,6 +1319,9 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13141319
}
13151320

13161321
self.items.push(item.item_id());
1322+
if self.crate_collector && item.has_delayed_lints {
1323+
self.delayed_lint_items.push(item.item_id().owner_id);
1324+
}
13171325

13181326
// Items that are modules are handled here instead of in visit_mod.
13191327
if let ItemKind::Mod(_, module) = &item.kind {
@@ -1329,6 +1337,9 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13291337

13301338
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
13311339
self.foreign_items.push(item.foreign_item_id());
1340+
if self.crate_collector && item.has_delayed_lints {
1341+
self.delayed_lint_items.push(item.foreign_item_id().owner_id);
1342+
}
13321343
intravisit::walk_foreign_item(self, item)
13331344
}
13341345

@@ -1362,6 +1373,10 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13621373
}
13631374

13641375
self.trait_items.push(item.trait_item_id());
1376+
if self.crate_collector && item.has_delayed_lints {
1377+
self.delayed_lint_items.push(item.trait_item_id().owner_id);
1378+
}
1379+
13651380
intravisit::walk_trait_item(self, item)
13661381
}
13671382

@@ -1371,6 +1386,10 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13711386
}
13721387

13731388
self.impl_items.push(item.impl_item_id());
1389+
if self.crate_collector && item.has_delayed_lints {
1390+
self.delayed_lint_items.push(item.impl_item_id().owner_id);
1391+
}
1392+
13741393
intravisit::walk_impl_item(self, item)
13751394
}
13761395
}

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub struct ModuleItems {
3232
opaques: Box<[LocalDefId]>,
3333
body_owners: Box<[LocalDefId]>,
3434
nested_bodies: Box<[LocalDefId]>,
35+
// only filled with hir_crate_items, not with hir_module_items
36+
delayed_lint_items: Box<[OwnerId]>,
3537
}
3638

3739
impl ModuleItems {
@@ -49,6 +51,10 @@ impl ModuleItems {
4951
self.trait_items.iter().copied()
5052
}
5153

54+
pub fn delayed_lint_items(&self) -> impl Iterator<Item = OwnerId> {
55+
self.delayed_lint_items.iter().copied()
56+
}
57+
5258
/// Returns all items that are associated with some `impl` block (both inherent and trait impl
5359
/// blocks).
5460
pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> {

0 commit comments

Comments
 (0)