Skip to content

Commit 5afd6e4

Browse files
committed
Invoke hir_crate_items before force_delayed_lowering, don't force lowering in print
1 parent e3691a5 commit 5afd6e4

File tree

14 files changed

+264
-84
lines changed

14 files changed

+264
-84
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub(super) enum Owners<'a, 'hir> {
3838
}
3939

4040
impl<'hir> Owners<'_, 'hir> {
41-
fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> {
41+
pub(super) fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> {
4242
match self {
4343
Owners::IndexVec(index_vec) => {
4444
index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom)

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use std::mem;
3939
use std::sync::Arc;
4040

4141
use rustc_ast::node_id::NodeMap;
42+
use rustc_ast::visit::AssocCtxt;
4243
use rustc_ast::{self as ast, *};
4344
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
4445
use rustc_data_structures::fingerprint::Fingerprint;
@@ -53,8 +54,8 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
5354
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
5455
use rustc_hir::lints::{AttributeLint, DelayedLint};
5556
use rustc_hir::{
56-
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
57-
LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,
57+
self as hir, AngleBrackets, ConstArg, DelayedOwner, GenericArg, HirId, ItemLocalMap,
58+
LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,
5859
};
5960
use rustc_index::{Idx, IndexSlice, IndexVec};
6061
use rustc_macros::extension;
@@ -633,13 +634,35 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
633634
let mut delayed_ids: FxIndexSet<LocalDefId> = Default::default();
634635

635636
for def_id in ast_index.indices() {
636-
match &ast_index[def_id] {
637-
AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. })
638-
| AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => {
639-
delayed_ids.insert(def_id);
637+
let delayed_owner = match &ast_index[def_id] {
638+
AstOwner::Item(Item {
639+
kind: ItemKind::Delegation(box Delegation { ident, .. }),
640+
..
641+
}) => Some(DelayedOwner { kind: hir::DelayedOwnerKind::Item, ident: Some(*ident) }),
642+
AstOwner::AssocItem(
643+
Item { kind: AssocItemKind::Delegation(box Delegation { ident, .. }), .. },
644+
ctx,
645+
) => {
646+
let kind = match ctx {
647+
AssocCtxt::Trait => hir::DelayedOwnerKind::TraitItem,
648+
AssocCtxt::Impl { .. } => hir::DelayedOwnerKind::ImplItem,
649+
};
650+
651+
Some(DelayedOwner { kind, ident: Some(*ident) })
640652
}
641-
_ => lowerer.lower_node(def_id),
653+
_ => None,
642654
};
655+
656+
if let Some(delayed_owner) = delayed_owner {
657+
delayed_ids.insert(def_id);
658+
659+
let owner = lowerer.owners.get_or_insert_mut(def_id);
660+
if let hir::MaybeOwner::Phantom = owner {
661+
*owner = hir::MaybeOwner::Delayed(delayed_owner)
662+
}
663+
} else {
664+
lowerer.lower_node(def_id);
665+
}
643666
}
644667

645668
// Don't hash unless necessary, because it's expensive.

compiler/rustc_hir/src/hir.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,10 +1641,24 @@ impl<'tcx> OwnerInfo<'tcx> {
16411641
}
16421642
}
16431643

1644+
#[derive(Copy, Clone, Debug, HashStable_Generic)]
1645+
pub enum DelayedOwnerKind {
1646+
Item,
1647+
ImplItem,
1648+
TraitItem,
1649+
}
1650+
1651+
#[derive(Copy, Clone, Debug, HashStable_Generic)]
1652+
pub struct DelayedOwner {
1653+
pub ident: Option<Ident>,
1654+
pub kind: DelayedOwnerKind,
1655+
}
1656+
16441657
#[derive(Copy, Clone, Debug, HashStable_Generic)]
16451658
pub enum MaybeOwner<'tcx> {
16461659
Owner(&'tcx OwnerInfo<'tcx>),
16471660
NonOwner(HirId),
1661+
Delayed(DelayedOwner),
16481662
/// Used as a placeholder for unused LocalDefId.
16491663
Phantom,
16501664
}
@@ -1653,12 +1667,16 @@ impl<'tcx> MaybeOwner<'tcx> {
16531667
pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
16541668
match self {
16551669
MaybeOwner::Owner(i) => Some(i),
1656-
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
1670+
_ => None,
16571671
}
16581672
}
16591673

16601674
pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1661-
self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
1675+
self.as_owner().unwrap_or_else(|| panic!("not a HIR owner"))
1676+
}
1677+
1678+
pub fn expect_delayed(&self) -> DelayedOwner {
1679+
if let MaybeOwner::Delayed(kind) = self { *kind } else { panic!("not a delayed owner") }
16621680
}
16631681
}
16641682

compiler/rustc_hir/src/intravisit.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub trait HirTyCtxt<'hir> {
117117
fn hir_trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
118118
fn hir_impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
119119
fn hir_foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
120+
fn is_delayed(&self, id: LocalDefId) -> bool;
120121
}
121122

122123
// Used when no tcx is actually available, forcing manual implementation of nested visitors.
@@ -139,6 +140,9 @@ impl<'hir> HirTyCtxt<'hir> for ! {
139140
fn hir_foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
140141
unreachable!();
141142
}
143+
fn is_delayed(&self, _: LocalDefId) -> bool {
144+
unreachable!()
145+
}
142146
}
143147

144148
pub mod nested_filter {
@@ -226,6 +230,8 @@ pub trait Visitor<'v>: Sized {
226230
/// or `ControlFlow<T>`.
227231
type Result: VisitorResult = ();
228232

233+
const VISIT_DELAYED: bool = true;
234+
229235
/// If `type NestedFilter` is set to visit nested items, this method
230236
/// must also be overridden to provide a map to retrieve nested items.
231237
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
@@ -244,18 +250,23 @@ pub trait Visitor<'v>: Sized {
244250
/// this method is if you want a nested pattern but cannot supply a
245251
/// `TyCtxt`; see `maybe_tcx` for advice.
246252
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
247-
if Self::NestedFilter::INTER {
253+
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
248254
let item = self.maybe_tcx().hir_item(id);
249255
try_visit!(self.visit_item(item));
250256
}
251257
Self::Result::output()
252258
}
253259

260+
// Now delayed owners are only delegations, which are either item, trait item or impl item.
261+
fn should_visit_maybe_delayed_inter(&mut self, id: LocalDefId) -> bool {
262+
Self::NestedFilter::INTER && (Self::VISIT_DELAYED || !self.maybe_tcx().is_delayed(id))
263+
}
264+
254265
/// Like `visit_nested_item()`, but for trait items. See
255266
/// `visit_nested_item()` for advice on when to override this
256267
/// method.
257268
fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result {
258-
if Self::NestedFilter::INTER {
269+
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
259270
let item = self.maybe_tcx().hir_trait_item(id);
260271
try_visit!(self.visit_trait_item(item));
261272
}
@@ -266,7 +277,7 @@ pub trait Visitor<'v>: Sized {
266277
/// `visit_nested_item()` for advice on when to override this
267278
/// method.
268279
fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result {
269-
if Self::NestedFilter::INTER {
280+
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
270281
let item = self.maybe_tcx().hir_impl_item(id);
271282
try_visit!(self.visit_impl_item(item));
272283
}

compiler/rustc_interface/src/passes.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,10 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) {
10541054
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
10551055
/// This function never fails.
10561056
fn run_required_analyses(tcx: TyCtxt<'_>) {
1057+
// Forces all delayed owners to be lowered and drops AST crate after it.
1058+
// Also refetches hir_crate_items to prevent multiple threads from blocking on it later.
1059+
tcx.force_delayed_owners_lowering();
1060+
10571061
if tcx.sess.opts.unstable_opts.input_stats {
10581062
rustc_passes::input_stats::print_hir_stats(tcx);
10591063
}
@@ -1062,11 +1066,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10621066
#[cfg(all(not(doc), debug_assertions))]
10631067
rustc_passes::hir_id_validator::check_crate(tcx);
10641068

1065-
// Prefetch this to prevent multiple threads from blocking on it later.
1066-
// This is needed since the `hir_id_validator::check_crate` call above is not guaranteed
1067-
// to use `hir_crate_items`.
1068-
tcx.ensure_done().hir_crate_items(());
1069-
10701069
let sess = tcx.sess;
10711070
sess.time("misc_checking_1", || {
10721071
par_fns(&mut [

compiler/rustc_middle/src/hir/map.rs

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_ast::visit::{VisitorResult, walk_list};
77
use rustc_data_structures::fingerprint::Fingerprint;
88
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
99
use rustc_data_structures::svh::Svh;
10-
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in};
10+
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in};
1111
use rustc_hir::def::{DefKind, Res};
1212
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
1313
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -835,18 +835,8 @@ impl<'tcx> TyCtxt<'tcx> {
835835
}
836836

837837
#[inline]
838-
fn hir_opt_ident(self, id: HirId) -> Option<Ident> {
839-
match self.hir_node(id) {
840-
Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
841-
// A `Ctor` doesn't have an identifier itself, but its parent
842-
// struct/variant does. Compare with `hir::Map::span`.
843-
Node::Ctor(..) => match self.parent_hir_node(id) {
844-
Node::Item(item) => Some(item.kind.ident().unwrap()),
845-
Node::Variant(variant) => Some(variant.ident),
846-
_ => unreachable!(),
847-
},
848-
node => node.ident(),
849-
}
838+
pub fn hir_opt_ident(self, id: HirId) -> Option<Ident> {
839+
self.hir_crate(()).opt_ident(self, id)
850840
}
851841

852842
#[inline]
@@ -1115,6 +1105,10 @@ impl<'tcx> intravisit::HirTyCtxt<'tcx> for TyCtxt<'tcx> {
11151105
fn hir_foreign_item(&self, id: ForeignItemId) -> &'tcx ForeignItem<'tcx> {
11161106
(*self).hir_foreign_item(id)
11171107
}
1108+
1109+
fn is_delayed(&self, id: LocalDefId) -> bool {
1110+
(*self).hir_crate(()).delayed_ids.contains(&id)
1111+
}
11181112
}
11191113

11201114
impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> {
@@ -1212,8 +1206,14 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
12121206
upstream_crates
12131207
}
12141208

1209+
#[derive(Clone, Copy)]
1210+
enum ItemCollectionKind {
1211+
Crate,
1212+
Mod(LocalModDefId),
1213+
}
1214+
12151215
pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems {
1216-
let mut collector = ItemCollector::new(tcx, false);
1216+
let mut collector = ItemCollector::new(tcx, ItemCollectionKind::Mod(module_id));
12171217

12181218
let (hir_mod, span, hir_id) = tcx.hir_get_module(module_id);
12191219
collector.visit_mod(hir_mod, span, hir_id);
@@ -1245,26 +1245,8 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
12451245
}
12461246
}
12471247

1248-
fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) {
1249-
let krate = tcx.hir_crate(());
1250-
for &id in &krate.delayed_ids {
1251-
tcx.ensure_done().lower_delayed_owner(id);
1252-
}
1253-
1254-
let (_, krate) = krate.delayed_resolver.steal();
1255-
let prof = tcx.sess.prof.clone();
1256-
1257-
// Drop AST to free memory. It can be expensive so try to drop it on a separate thread.
1258-
spawn(move || {
1259-
let _timer = prof.verbose_generic_activity("drop_ast");
1260-
drop(krate);
1261-
});
1262-
}
1263-
12641248
pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1265-
force_delayed_owners_lowering(tcx);
1266-
1267-
let mut collector = ItemCollector::new(tcx, true);
1249+
let mut collector = ItemCollector::new(tcx, ItemCollectionKind::Crate);
12681250

12691251
// A "crate collector" and "module collector" start at a
12701252
// module item (the former starts at the crate root) but only
@@ -1327,9 +1309,9 @@ struct ItemCollector<'tcx> {
13271309
}
13281310

13291311
impl<'tcx> ItemCollector<'tcx> {
1330-
fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> {
1331-
ItemCollector {
1332-
crate_collector,
1312+
fn new(tcx: TyCtxt<'tcx>, collection_kind: ItemCollectionKind) -> ItemCollector<'tcx> {
1313+
let mut collector = ItemCollector {
1314+
crate_collector: matches!(collection_kind, ItemCollectionKind::Crate),
13331315
tcx,
13341316
submodules: Vec::default(),
13351317
items: Vec::default(),
@@ -1341,12 +1323,34 @@ impl<'tcx> ItemCollector<'tcx> {
13411323
nested_bodies: Vec::default(),
13421324
delayed_lint_items: Vec::default(),
13431325
eiis: Vec::default(),
1326+
};
1327+
1328+
let delayed_kinds = tcx.hir_crate(()).delayed_owners_kinds();
1329+
let delayed_kinds = delayed_kinds.filter(|(id, _)| match collection_kind {
1330+
ItemCollectionKind::Crate => true,
1331+
ItemCollectionKind::Mod(mod_id) => tcx.parent_module_from_def_id(*id) == mod_id,
1332+
});
1333+
1334+
// FIXME(fn_delegation): need to add delayed lints, eiis
1335+
for (def_id, kind) in delayed_kinds {
1336+
let owner_id = OwnerId { def_id };
1337+
1338+
match kind {
1339+
DelayedOwnerKind::Item => collector.items.push(ItemId { owner_id }),
1340+
DelayedOwnerKind::ImplItem => collector.impl_items.push(ImplItemId { owner_id }),
1341+
DelayedOwnerKind::TraitItem => collector.trait_items.push(TraitItemId { owner_id }),
1342+
};
1343+
1344+
collector.body_owners.push(def_id);
13441345
}
1346+
1347+
collector
13451348
}
13461349
}
13471350

13481351
impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13491352
type NestedFilter = nested_filter::All;
1353+
const VISIT_DELAYED: bool = false;
13501354

13511355
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
13521356
self.tcx

0 commit comments

Comments
 (0)