Skip to content

Commit 192daf4

Browse files
authored
Unrolled build for #155226
Rollup merge of #155226 - aerooneqq:delegation-hir-crate-items-revert, r=petrochenkov delegation: revert execution of hir_crate_items before delayed lowering This PR reverts #154368, as after weekend consideration I don't think that it is a correct way of fixing cycles during delayed lowering: - The number of ICEs were reported, fixing them would require to develop solution from #154368 but I am afraid that it would lead to cancer code growing, - The [memory regression](#154368 (comment)) for rustdoc was reported, it can be fixed with moving `tcx.force_delayed_owners_lowering` call earlier, but it is already bad that this is call is now required everywhere, before #154368 AST was dropped before `hir_crate_items` automatically and users of `rustc` API did not have to think about it. I will try to come up with a more robust solution leaving #154368 as a last resort if nothing else will work. Re-opens #154169. Fixes #155125. Fixes #155127. Fixes #155128. Fixes #155164. Fixes #155202. Part of #118212. r? @petrochenkov
2 parents 14196db + d283703 commit 192daf4

17 files changed

Lines changed: 232 additions & 313 deletions

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
433433
// also nested delegations may need to access information about this code (#154332),
434434
// so it is better to leave this code as opposed to bodies of extern functions,
435435
// which are completely erased from existence.
436-
// FIXME(fn_delegation): fix `help` in error message (see `inner-attr.stderr`)
437436
if param_count == 0
438437
&& let Some(block) = block
439438
{

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-
pub(super) fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> {
41+
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: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ use std::mem;
3939
use std::sync::Arc;
4040

4141
use rustc_ast::node_id::NodeMap;
42-
use rustc_ast::visit::AssocCtxt;
4342
use rustc_ast::{self as ast, *};
4443
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
4544
use rustc_data_structures::fingerprint::Fingerprint;
@@ -634,29 +633,13 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
634633
let mut delayed_ids: FxIndexSet<LocalDefId> = Default::default();
635634

636635
for def_id in ast_index.indices() {
637-
let delayed_owner_kind = match &ast_index[def_id] {
638-
AstOwner::Item(Item { kind: ItemKind::Delegation(_), .. }) => {
639-
Some(hir::DelayedOwnerKind::Item)
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);
640640
}
641-
AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(_), .. }, ctx) => {
642-
Some(match ctx {
643-
AssocCtxt::Trait => hir::DelayedOwnerKind::TraitItem,
644-
AssocCtxt::Impl { .. } => hir::DelayedOwnerKind::ImplItem,
645-
})
646-
}
647-
_ => None,
641+
_ => lowerer.lower_node(def_id),
648642
};
649-
650-
if let Some(kind) = delayed_owner_kind {
651-
delayed_ids.insert(def_id);
652-
653-
let owner = lowerer.owners.get_or_insert_mut(def_id);
654-
if let hir::MaybeOwner::Phantom = owner {
655-
*owner = hir::MaybeOwner::Delayed(kind)
656-
}
657-
} else {
658-
lowerer.lower_node(def_id);
659-
}
660643
}
661644

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

compiler/rustc_hir/src/hir.rs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,18 +1641,10 @@ 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-
16511644
#[derive(Copy, Clone, Debug, HashStable_Generic)]
16521645
pub enum MaybeOwner<'tcx> {
16531646
Owner(&'tcx OwnerInfo<'tcx>),
16541647
NonOwner(HirId),
1655-
Delayed(DelayedOwnerKind),
16561648
/// Used as a placeholder for unused LocalDefId.
16571649
Phantom,
16581650
}
@@ -1661,19 +1653,12 @@ impl<'tcx> MaybeOwner<'tcx> {
16611653
pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
16621654
match self {
16631655
MaybeOwner::Owner(i) => Some(i),
1664-
_ => None,
1656+
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
16651657
}
16661658
}
16671659

16681660
pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
1669-
self.as_owner().unwrap_or_else(|| panic!("not a HIR owner"))
1670-
}
1671-
1672-
pub fn expect_delayed(self) -> DelayedOwnerKind {
1673-
match self {
1674-
MaybeOwner::Delayed(delayed_owner) => delayed_owner,
1675-
_ => panic!("not a delayed owner"),
1676-
}
1661+
self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
16771662
}
16781663
}
16791664

compiler/rustc_hir/src/intravisit.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,6 @@ pub trait Visitor<'v>: Sized {
226226
/// or `ControlFlow<T>`.
227227
type Result: VisitorResult = ();
228228

229-
#[inline]
230-
fn visit_if_delayed(&self, _: LocalDefId) -> bool {
231-
true
232-
}
233-
234229
/// If `type NestedFilter` is set to visit nested items, this method
235230
/// must also be overridden to provide a map to retrieve nested items.
236231
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
@@ -249,23 +244,18 @@ pub trait Visitor<'v>: Sized {
249244
/// this method is if you want a nested pattern but cannot supply a
250245
/// `TyCtxt`; see `maybe_tcx` for advice.
251246
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
252-
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
247+
if Self::NestedFilter::INTER {
253248
let item = self.maybe_tcx().hir_item(id);
254249
try_visit!(self.visit_item(item));
255250
}
256251
Self::Result::output()
257252
}
258253

259-
// Now delayed owners are only delegations, which are either item, trait item or impl item.
260-
fn should_visit_maybe_delayed_inter(&mut self, id: LocalDefId) -> bool {
261-
Self::NestedFilter::INTER && self.visit_if_delayed(id)
262-
}
263-
264254
/// Like `visit_nested_item()`, but for trait items. See
265255
/// `visit_nested_item()` for advice on when to override this
266256
/// method.
267257
fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result {
268-
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
258+
if Self::NestedFilter::INTER {
269259
let item = self.maybe_tcx().hir_trait_item(id);
270260
try_visit!(self.visit_trait_item(item));
271261
}
@@ -276,7 +266,7 @@ pub trait Visitor<'v>: Sized {
276266
/// `visit_nested_item()` for advice on when to override this
277267
/// method.
278268
fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result {
279-
if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) {
269+
if Self::NestedFilter::INTER {
280270
let item = self.maybe_tcx().hir_impl_item(id);
281271
try_visit!(self.visit_impl_item(item));
282272
}

compiler/rustc_interface/src/passes.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,10 +1054,6 @@ 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-
10611057
if tcx.sess.opts.unstable_opts.input_stats {
10621058
rustc_passes::input_stats::print_hir_stats(tcx);
10631059
}
@@ -1066,6 +1062,11 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10661062
#[cfg(all(not(doc), debug_assertions))]
10671063
rustc_passes::hir_id_validator::check_crate(tcx);
10681064

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+
10691070
let sess = tcx.sess;
10701071
sess.time("misc_checking_1", || {
10711072
par_fns(&mut [

compiler/rustc_middle/src/hir/map.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
use rustc_abi::ExternAbi;
66
use rustc_ast::visit::{VisitorResult, walk_list};
77
use rustc_data_structures::fingerprint::Fingerprint;
8-
use rustc_data_structures::fx::FxIndexSet;
98
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
109
use rustc_data_structures::svh::Svh;
11-
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in};
10+
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in};
1211
use rustc_hir::def::{DefKind, Res};
1312
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
1413
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -1246,7 +1245,25 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
12461245
}
12471246
}
12481247

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+
12491264
pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1265+
force_delayed_owners_lowering(tcx);
1266+
12501267
let mut collector = ItemCollector::new(tcx, true);
12511268

12521269
// A "crate collector" and "module collector" start at a
@@ -1307,12 +1324,11 @@ struct ItemCollector<'tcx> {
13071324
nested_bodies: Vec<LocalDefId>,
13081325
delayed_lint_items: Vec<OwnerId>,
13091326
eiis: Vec<LocalDefId>,
1310-
delayed_ids: Option<&'tcx FxIndexSet<LocalDefId>>,
13111327
}
13121328

13131329
impl<'tcx> ItemCollector<'tcx> {
13141330
fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> {
1315-
let mut collector = ItemCollector {
1331+
ItemCollector {
13161332
crate_collector,
13171333
tcx,
13181334
submodules: Vec::default(),
@@ -1325,46 +1341,13 @@ impl<'tcx> ItemCollector<'tcx> {
13251341
nested_bodies: Vec::default(),
13261342
delayed_lint_items: Vec::default(),
13271343
eiis: Vec::default(),
1328-
delayed_ids: None,
1329-
};
1330-
1331-
if crate_collector {
1332-
let krate = tcx.hir_crate(());
1333-
collector.delayed_ids = Some(&krate.delayed_ids);
1334-
1335-
let delayed_kinds =
1336-
krate.delayed_ids.iter().copied().map(|id| (id, krate.owners[id].expect_delayed()));
1337-
1338-
// FIXME(fn_delegation): need to add delayed lints, eiis
1339-
for (def_id, kind) in delayed_kinds {
1340-
let owner_id = OwnerId { def_id };
1341-
1342-
match kind {
1343-
DelayedOwnerKind::Item => collector.items.push(ItemId { owner_id }),
1344-
DelayedOwnerKind::ImplItem => {
1345-
collector.impl_items.push(ImplItemId { owner_id })
1346-
}
1347-
DelayedOwnerKind::TraitItem => {
1348-
collector.trait_items.push(TraitItemId { owner_id })
1349-
}
1350-
};
1351-
1352-
collector.body_owners.push(def_id);
1353-
}
13541344
}
1355-
1356-
collector
13571345
}
13581346
}
13591347

13601348
impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13611349
type NestedFilter = nested_filter::All;
13621350

1363-
#[inline]
1364-
fn visit_if_delayed(&self, def_id: LocalDefId) -> bool {
1365-
!self.crate_collector || self.delayed_ids.is_none_or(|ids| !ids.contains(&def_id))
1366-
}
1367-
13681351
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
13691352
self.tcx
13701353
}

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxIndexSet;
1414
use rustc_data_structures::sorted_map::SortedMap;
1515
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1616
use rustc_data_structures::steal::Steal;
17-
use rustc_data_structures::sync::{DynSend, DynSync, spawn, try_par_for_each_in};
17+
use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in};
1818
use rustc_hir::def::{DefKind, Res};
1919
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
2020
use rustc_hir::lints::DelayedLint;
@@ -64,8 +64,7 @@ impl<'hir> Crate<'hir> {
6464
// which is greater than delayed LocalDefId, we use IndexVec for owners,
6565
// so we will call ensure_contains_elem which will grow it.
6666
if let Some(owner) = self.owners.get(def_id)
67-
&& (self.delayed_ids.is_empty()
68-
|| !matches!(owner, MaybeOwner::Phantom | MaybeOwner::Delayed(_)))
67+
&& (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom))
6968
{
7069
return *owner;
7170
}
@@ -208,24 +207,6 @@ impl ModuleItems {
208207
}
209208

210209
impl<'tcx> TyCtxt<'tcx> {
211-
pub fn force_delayed_owners_lowering(self) {
212-
let krate = self.hir_crate(());
213-
self.ensure_done().hir_crate_items(());
214-
215-
for &id in &krate.delayed_ids {
216-
self.ensure_done().lower_delayed_owner(id);
217-
}
218-
219-
let (_, krate) = krate.delayed_resolver.steal();
220-
let prof = self.sess.prof.clone();
221-
222-
// Drop AST to free memory. It can be expensive so try to drop it on a separate thread.
223-
spawn(move || {
224-
let _timer = prof.verbose_generic_activity("drop_ast");
225-
drop(krate);
226-
});
227-
}
228-
229210
pub fn parent_module(self, id: HirId) -> LocalModDefId {
230211
if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
231212
LocalModDefId::new_unchecked(id.owner.def_id)
@@ -494,8 +475,7 @@ pub fn provide(providers: &mut Providers) {
494475
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) {
495476
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
496477
MaybeOwner::NonOwner(hir_id) => hir_id,
497-
MaybeOwner::Phantom => bug!("no HirId for {:?}", def_id),
498-
MaybeOwner::Delayed(_) => bug!("delayed owner should be lowered {:?}", def_id),
478+
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
499479
};
500480
providers.opt_hir_owner_nodes =
501481
|tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes);

src/librustdoc/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,6 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
904904
return;
905905
}
906906

907-
tcx.force_delayed_owners_lowering();
908907
rustc_interface::passes::emit_delayed_lints(tcx);
909908

910909
if render_opts.dep_info().is_some() {

tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ help: consider introducing lifetime `'a` here
4343
LL | impl<'a> Trait for Z {
4444
| ++++
4545

46+
error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope
47+
--> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41
48+
|
49+
LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
50+
| -------------------------------------- associated function or constant `new` not found for this struct
51+
...
52+
LL | pub const NEW: Self = InvariantRef::new(&());
53+
| ^^^ associated function or constant not found in `InvariantRef<'_, _>`
54+
4655
error[E0277]: the trait bound `u8: Trait` is not satisfied
4756
--> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12
4857
|
@@ -110,15 +119,6 @@ LL | reuse <u8 as Trait>::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW
110119
found struct `InvariantRef<'_, ()>`
111120
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
112121

113-
error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope
114-
--> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41
115-
|
116-
LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
117-
| -------------------------------------- associated function or constant `new` not found for this struct
118-
...
119-
LL | pub const NEW: Self = InvariantRef::new(&());
120-
| ^^^ associated function or constant not found in `InvariantRef<'_, _>`
121-
122122
error: aborting due to 10 previous errors
123123

124124
Some errors have detailed explanations: E0261, E0277, E0308, E0599.

0 commit comments

Comments
 (0)