Skip to content

Commit b889cc9

Browse files
committed
Split the resolver tables into per-owner tables, starting with node_id_to_def_id
1 parent 3e45c29 commit b889cc9

File tree

10 files changed

+311
-95
lines changed

10 files changed

+311
-95
lines changed

compiler/rustc_ast_lowering/src/item.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8787

8888
#[instrument(level = "debug", skip(self, c))]
8989
fn lower_crate(&mut self, c: &Crate) {
90-
debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
90+
debug_assert_eq!(
91+
self.resolver.owners[&CRATE_NODE_ID].node_id_to_def_id[&CRATE_NODE_ID],
92+
CRATE_DEF_ID
93+
);
9194
self.with_lctx(CRATE_NODE_ID, |lctx| {
9295
let module = lctx.lower_mod(&c.items, &c.spans);
9396
// FIXME(jdonszelman): is dummy span ever a problem here?
@@ -101,6 +104,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
101104
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
102105
}
103106

107+
#[instrument(level = "debug", skip(self))]
104108
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
105109
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
106110
}

compiler/rustc_ast_lowering/src/lib.rs

+64-10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#![doc(rust_logo)]
3737
#![feature(assert_matches)]
3838
#![feature(box_patterns)]
39+
#![feature(closure_track_caller)]
3940
#![feature(exact_size_is_empty)]
4041
#![feature(if_let_guard)]
4142
#![feature(let_chains)]
@@ -60,7 +61,7 @@ use rustc_hir::{
6061
};
6162
use rustc_index::{Idx, IndexSlice, IndexVec};
6263
use rustc_middle::span_bug;
63-
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
64+
use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};
6465
use rustc_session::parse::{add_feature_diagnostics, feature_err};
6566
use rustc_span::symbol::{Ident, Symbol, kw, sym};
6667
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
@@ -152,7 +153,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
152153
Self {
153154
// Pseudo-globals.
154155
tcx,
155-
resolver: PerOwnerResolver { general: resolver },
156+
resolver: PerOwnerResolver {
157+
general: resolver,
158+
item: PerOwnerResolverData::new(DUMMY_NODE_ID),
159+
},
156160
arena: tcx.hir_arena,
157161

158162
// HirId handling.
@@ -202,6 +206,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
202206

203207
pub(crate) struct PerOwnerResolver<'a> {
204208
pub general: &'a mut ResolverAstLowering,
209+
pub item: PerOwnerResolverData,
210+
}
211+
212+
impl<'a> std::ops::Deref for PerOwnerResolver<'a> {
213+
type Target = PerOwnerResolverData;
214+
215+
fn deref(&self) -> &Self::Target {
216+
&self.item
217+
}
205218
}
206219

207220
impl PerOwnerResolver<'_> {
@@ -369,17 +382,22 @@ enum AstOwner<'a> {
369382
}
370383

371384
fn index_crate<'a>(
372-
node_id_to_def_id: &NodeMap<LocalDefId>,
385+
owners: &NodeMap<PerOwnerResolverData>,
373386
krate: &'a Crate,
374387
) -> IndexVec<LocalDefId, AstOwner<'a>> {
375-
let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
388+
let mut indexer = Indexer {
389+
owners,
390+
node_id_to_def_id: &owners[&CRATE_NODE_ID].node_id_to_def_id,
391+
index: IndexVec::new(),
392+
};
376393
*indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
377394
AstOwner::Crate(krate);
378395
visit::walk_crate(&mut indexer, krate);
379396
return indexer.index;
380397

381398
struct Indexer<'s, 'a> {
382399
node_id_to_def_id: &'s NodeMap<LocalDefId>,
400+
owners: &'s NodeMap<PerOwnerResolverData>,
383401
index: IndexVec<LocalDefId, AstOwner<'a>>,
384402
}
385403

@@ -390,23 +408,38 @@ fn index_crate<'a>(
390408
}
391409

392410
fn visit_item(&mut self, item: &'a ast::Item) {
411+
let old = std::mem::replace(
412+
&mut self.node_id_to_def_id,
413+
&self.owners[&item.id].node_id_to_def_id,
414+
);
393415
let def_id = self.node_id_to_def_id[&item.id];
394416
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
395-
visit::walk_item(self, item)
417+
visit::walk_item(self, item);
418+
self.node_id_to_def_id = old;
396419
}
397420

398421
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
422+
let old = std::mem::replace(
423+
&mut self.node_id_to_def_id,
424+
&self.owners[&item.id].node_id_to_def_id,
425+
);
399426
let def_id = self.node_id_to_def_id[&item.id];
400427
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
401428
AstOwner::AssocItem(item, ctxt);
402429
visit::walk_assoc_item(self, item, ctxt);
430+
self.node_id_to_def_id = old;
403431
}
404432

405433
fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
434+
let old = std::mem::replace(
435+
&mut self.node_id_to_def_id,
436+
&self.owners[&item.id].node_id_to_def_id,
437+
);
406438
let def_id = self.node_id_to_def_id[&item.id];
407439
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
408440
AstOwner::ForeignItem(item);
409441
visit::walk_item(self, item);
442+
self.node_id_to_def_id = old;
410443
}
411444
}
412445
}
@@ -443,7 +476,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
443476
tcx.ensure_done().get_lang_items(());
444477
let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
445478

446-
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
479+
let ast_index = index_crate(&resolver.owners, &krate);
447480
let mut owners = IndexVec::from_fn_n(
448481
|_| hir::MaybeOwner::Phantom,
449482
tcx.definitions_untracked().def_index_count(),
@@ -518,7 +551,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
518551
self.tcx.at(span).create_def(self.current_hir_id_owner.def_id, name, def_kind).def_id();
519552

520553
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
521-
self.resolver.general.node_id_to_def_id.insert(node_id, def_id);
554+
self.resolver.item.node_id_to_def_id.insert(node_id, def_id);
522555

523556
def_id
524557
}
@@ -533,16 +566,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
533566
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
534567
/// resolver (if any).
535568
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
536-
self.resolver.general.node_id_to_def_id.get(&node).copied()
569+
self.resolver.node_id_to_def_id.get(&node).copied()
537570
}
538571

539572
fn local_def_id(&self, node: NodeId) -> LocalDefId {
540-
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
573+
self.opt_local_def_id(node).unwrap_or_else(|| {
574+
self.resolver.general.owners.items().any(|(id, items)| {
575+
items.node_id_to_def_id.items().any(|(node_id, def_id)| {
576+
if *node_id == node {
577+
panic!(
578+
"{def_id:?} ({node_id}) was found in {:?} ({id})",
579+
items.node_id_to_def_id.get(id),
580+
)
581+
}
582+
false
583+
})
584+
});
585+
panic!("no entry for node id: `{node:?}`");
586+
})
541587
}
542588

543589
/// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.
544590
fn owner_id(&self, node: NodeId) -> hir::OwnerId {
545-
hir::OwnerId { def_id: self.local_def_id(node) }
591+
hir::OwnerId { def_id: self.resolver.general.owners[&node].node_id_to_def_id[&node] }
546592
}
547593

548594
/// Freshen the `LoweringContext` and ready it to lower a nested item.
@@ -561,6 +607,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
561607
let current_attrs = std::mem::take(&mut self.attrs);
562608
let current_bodies = std::mem::take(&mut self.bodies);
563609
let current_define_opaque = std::mem::take(&mut self.define_opaque);
610+
let current_ast_owner = std::mem::replace(
611+
&mut self.resolver.item,
612+
self.resolver.general.owners.remove(&owner).unwrap(),
613+
);
564614
let current_ident_and_label_to_local_id =
565615
std::mem::take(&mut self.ident_and_label_to_local_id);
566616

@@ -606,6 +656,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
606656
self.impl_trait_defs = current_impl_trait_defs;
607657
self.impl_trait_bounds = current_impl_trait_bounds;
608658

659+
let _prev_owner_data = std::mem::replace(&mut self.resolver.item, current_ast_owner);
660+
#[cfg(debug_assertions)]
661+
self.resolver.general.owners.insert(owner, _prev_owner_data);
662+
609663
debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
610664
self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
611665
}

compiler/rustc_expand/src/base.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,13 @@ pub trait ResolverExpand {
11161116
trait_def_id: DefId,
11171117
impl_def_id: LocalDefId,
11181118
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1119+
1120+
/// Set a new owner and return the old one. Use only in the implementation
1121+
/// of `with_owner` and always call [Self::reset_owner] afterwards
1122+
fn set_owner(&mut self, id: NodeId) -> NodeId;
1123+
1124+
/// Switch back to the original owner.
1125+
fn reset_owner(&mut self, id: NodeId);
11191126
}
11201127

11211128
pub trait LintStoreExpand {

compiler/rustc_expand/src/expand.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ use std::rc::Rc;
44
use std::sync::Arc;
55
use std::{iter, mem};
66

7-
use rustc_ast as ast;
87
use rustc_ast::mut_visit::*;
98
use rustc_ast::ptr::P;
109
use rustc_ast::token::{self, Delimiter};
1110
use rustc_ast::tokenstream::TokenStream;
1211
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
1312
use rustc_ast::{
14-
AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind, ForeignItemKind,
15-
HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind,
16-
NodeId, PatKind, StmtKind, TyKind,
13+
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, CRATE_NODE_ID,
14+
DUMMY_NODE_ID, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle,
15+
MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind,
1716
};
1817
use rustc_ast_pretty::pprust;
1918
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
@@ -2178,34 +2177,45 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21782177
};
21792178
}
21802179
}
2180+
2181+
fn with_owner<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
2182+
if id == DUMMY_NODE_ID {
2183+
f(self)
2184+
} else {
2185+
let old = self.cx.resolver.set_owner(id);
2186+
let val = f(self);
2187+
self.cx.resolver.reset_owner(old);
2188+
val
2189+
}
2190+
}
21812191
}
21822192

21832193
impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
21842194
fn flat_map_item(&mut self, node: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
2185-
self.flat_map_node(node)
2195+
self.with_owner(node.id, |this| this.flat_map_node(node))
21862196
}
21872197

21882198
fn flat_map_assoc_item(
21892199
&mut self,
21902200
node: P<ast::AssocItem>,
21912201
ctxt: AssocCtxt,
21922202
) -> SmallVec<[P<ast::AssocItem>; 1]> {
2193-
match ctxt {
2194-
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
2203+
self.with_owner(node.id, |this| match ctxt {
2204+
AssocCtxt::Trait => this.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
21952205
AssocCtxt::Impl { of_trait: false } => {
2196-
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
2206+
this.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
21972207
}
21982208
AssocCtxt::Impl { of_trait: true } => {
2199-
self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
2209+
this.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
22002210
}
2201-
}
2211+
})
22022212
}
22032213

22042214
fn flat_map_foreign_item(
22052215
&mut self,
22062216
node: P<ast::ForeignItem>,
22072217
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
2208-
self.flat_map_node(node)
2218+
self.with_owner(node.id, |this| this.flat_map_node(node))
22092219
}
22102220

22112221
fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
@@ -2276,7 +2286,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
22762286
}
22772287

22782288
fn visit_crate(&mut self, node: &mut ast::Crate) {
2279-
self.visit_node(node)
2289+
self.with_owner(CRATE_NODE_ID, |this| this.visit_node(node))
22802290
}
22812291

22822292
fn visit_ty(&mut self, node: &mut P<ast::Ty>) {

compiler/rustc_middle/src/ty/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ pub struct ResolverGlobalCtxt {
187187
pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
188188
}
189189

190+
#[derive(Debug)]
191+
pub struct PerOwnerResolverData {
192+
pub node_id_to_def_id: NodeMap<LocalDefId>,
193+
/// The id of the owner
194+
pub id: ast::NodeId,
195+
}
196+
197+
impl PerOwnerResolverData {
198+
pub fn new(id: ast::NodeId) -> Self {
199+
Self { node_id_to_def_id: Default::default(), id }
200+
}
201+
}
202+
190203
/// Resolutions that should only be used for lowering.
191204
/// This struct is meant to be consumed by lowering.
192205
#[derive(Debug)]
@@ -204,9 +217,9 @@ pub struct ResolverAstLowering {
204217
/// Lifetime parameters that lowering will have to introduce.
205218
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
206219

207-
pub next_node_id: ast::NodeId,
220+
pub owners: NodeMap<PerOwnerResolverData>,
208221

209-
pub node_id_to_def_id: NodeMap<LocalDefId>,
222+
pub next_node_id: ast::NodeId,
210223

211224
pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
212225
/// List functions and methods for which lifetime elision was successful.

compiler/rustc_passes/src/lang_items.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
291291

292292
self.check_for_lang(
293293
target,
294-
self.resolver.node_id_to_def_id[&i.id],
294+
self.resolver.owners[&i.id].node_id_to_def_id[&i.id],
295295
&i.attrs,
296296
i.span,
297297
i.opt_generics(),
@@ -306,7 +306,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
306306
for variant in &enum_definition.variants {
307307
self.check_for_lang(
308308
Target::Variant,
309-
self.resolver.node_id_to_def_id[&variant.id],
309+
self.resolver.owners[&self.parent_item.unwrap().id].node_id_to_def_id[&variant.id],
310310
&variant.attrs,
311311
variant.span,
312312
None,
@@ -348,7 +348,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
348348

349349
self.check_for_lang(
350350
target,
351-
self.resolver.node_id_to_def_id[&i.id],
351+
self.resolver.owners[&i.id].node_id_to_def_id[&i.id],
352352
&i.attrs,
353353
i.span,
354354
generics,

0 commit comments

Comments
 (0)