Skip to content

Commit 24b8bb1

Browse files
committed
Auto merge of rust-lang#93373 - spastorino:def_id_to_hir_id_refactor, r=oli-obk
Store def_id_to_hir_id as variant in hir_owner. If hir_owner is Owner(_), the LocalDefId is pointing to an owner, so the ItemLocalId is 0. If the HIR node does not exist, we store Phantom. Otherwise, we store the HirId associated to the LocalDefId. Related to rust-lang#89278 r? `@oli-obk`
2 parents 86f5e17 + bf1ca2e commit 24b8bb1

File tree

11 files changed

+116
-95
lines changed

11 files changed

+116
-95
lines changed

compiler/rustc_ast_lowering/src/item.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
105105
) -> T {
106106
let old_len = self.in_scope_lifetimes.len();
107107

108-
let parent_generics =
109-
match self.owners[parent_hir_id].as_ref().unwrap().node().expect_item().kind {
110-
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
111-
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
112-
_ => &[],
113-
};
108+
let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind {
109+
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
110+
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
111+
_ => &[],
112+
};
114113
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
115114
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
116115
_ => None,
@@ -480,6 +479,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
480479
.node_id_to_hir_id
481480
.insert(new_node_id, hir::HirId::make_owner(new_id));
482481
debug_assert!(_old.is_none());
482+
self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
483+
let _old = std::mem::replace(
484+
&mut self.owners[new_id],
485+
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
486+
);
487+
debug_assert!(matches!(_old, hir::MaybeOwner::Phantom));
483488
continue;
484489
};
485490
let ident = *ident;

compiler/rustc_ast_lowering/src/lib.rs

+11-18
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct LoweringContext<'a, 'hir: 'a> {
9898
arena: &'hir Arena<'hir>,
9999

100100
/// The items being lowered are collected here.
101-
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
101+
owners: IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
102102
/// Bodies inside the owner being lowered.
103103
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
104104
/// Attributes inside the owner being lowered.
@@ -291,7 +291,8 @@ pub fn lower_crate<'a, 'hir>(
291291
) -> &'hir hir::Crate<'hir> {
292292
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
293293

294-
let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count());
294+
let owners =
295+
IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, resolver.definitions().def_index_count());
295296
LoweringContext {
296297
sess,
297298
resolver,
@@ -402,19 +403,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
402403

403404
let hir_hash = self.compute_hir_hash();
404405

405-
let mut def_id_to_hir_id = IndexVec::default();
406-
407-
for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
408-
if let Some(def_id) = self.resolver.opt_local_def_id(node_id) {
409-
if def_id_to_hir_id.len() <= def_id.index() {
410-
def_id_to_hir_id.resize(def_id.index() + 1, None);
411-
}
412-
def_id_to_hir_id[def_id] = hir_id;
413-
}
414-
}
415-
416-
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
417-
418406
let krate = hir::Crate { owners: self.owners, hir_hash };
419407
self.arena.alloc(krate)
420408
}
@@ -427,7 +415,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
427415
.owners
428416
.iter_enumerated()
429417
.filter_map(|(def_id, info)| {
430-
let info = info.as_ref()?;
418+
let info = info.as_owner()?;
431419
let def_path_hash = definitions.def_path_hash(def_id);
432420
Some((def_path_hash, info))
433421
})
@@ -469,8 +457,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
469457
self.current_hir_id_owner = current_owner;
470458
self.item_local_id_counter = current_local_counter;
471459

472-
let _old = self.owners.insert(def_id, info);
473-
debug_assert!(_old.is_none());
460+
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
461+
self.owners[def_id] = hir::MaybeOwner::Owner(self.arena.alloc(info));
474462

475463
def_id
476464
}
@@ -488,6 +476,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
488476
None
489477
} else {
490478
let def_id = self.resolver.opt_local_def_id(node_id)?;
479+
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
480+
if let o @ hir::MaybeOwner::Phantom = &mut self.owners[def_id] {
481+
// Do not override a `MaybeOwner::Owner` that may already here.
482+
*o = hir::MaybeOwner::NonOwner(hir_id);
483+
}
491484
Some((hir_id.local_id, def_id))
492485
}
493486
})

compiler/rustc_hir/src/definitions.rs

+1-30
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
pub use crate::def_id::DefPathHash;
88
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
99
use crate::def_path_hash_map::DefPathHashMap;
10-
use crate::hir;
1110

1211
use rustc_data_structures::fx::FxHashMap;
1312
use rustc_data_structures::stable_hasher::StableHasher;
@@ -101,13 +100,6 @@ impl DefPathTable {
101100
pub struct Definitions {
102101
table: DefPathTable,
103102

104-
/// Only [`LocalDefId`]s for items and item-like are HIR owners.
105-
/// The associated `HirId` has a `local_id` of `0`.
106-
/// Generic parameters and closures are also assigned a `LocalDefId` but are not HIR owners.
107-
/// Their `HirId`s are defined by their position while lowering the enclosing owner.
108-
// FIXME(cjgillot) Some `LocalDefId`s from `use` items are dropped during lowering and lack a `HirId`.
109-
pub(super) def_id_to_hir_id: IndexVec<LocalDefId, Option<hir::HirId>>,
110-
111103
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
112104
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
113105

@@ -322,12 +314,6 @@ impl Definitions {
322314
})
323315
}
324316

325-
#[inline]
326-
#[track_caller]
327-
pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId {
328-
self.def_id_to_hir_id[id].unwrap()
329-
}
330-
331317
/// Adds a root definition (no parent) and a few other reserved definitions.
332318
pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
333319
let key = DefKey {
@@ -354,7 +340,6 @@ impl Definitions {
354340

355341
Definitions {
356342
table,
357-
def_id_to_hir_id: Default::default(),
358343
expansions_that_defined: Default::default(),
359344
def_id_to_span,
360345
stable_crate_id,
@@ -406,20 +391,6 @@ impl Definitions {
406391
def_id
407392
}
408393

409-
/// Initializes the `LocalDefId` to `HirId` mapping once it has been generated during
410-
/// AST to HIR lowering.
411-
pub fn init_def_id_to_hir_id_mapping(
412-
&mut self,
413-
mapping: IndexVec<LocalDefId, Option<hir::HirId>>,
414-
) {
415-
assert!(
416-
self.def_id_to_hir_id.is_empty(),
417-
"trying to initialize `LocalDefId` <-> `HirId` mappings twice"
418-
);
419-
420-
self.def_id_to_hir_id = mapping;
421-
}
422-
423394
pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId {
424395
self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root)
425396
}
@@ -431,7 +402,7 @@ impl Definitions {
431402
}
432403

433404
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
434-
self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
405+
self.table.def_path_hashes.indices().map(|local_def_index| LocalDefId { local_def_index })
435406
}
436407

437408
#[inline(always)]

compiler/rustc_hir/src/hir.rs

+43-5
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,15 @@ pub struct OwnerNodes<'tcx> {
711711
pub local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
712712
}
713713

714+
impl<'tcx> OwnerNodes<'tcx> {
715+
pub fn node(&self) -> OwnerNode<'tcx> {
716+
use rustc_index::vec::Idx;
717+
let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
718+
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
719+
node
720+
}
721+
}
722+
714723
/// Full information resulting from lowering an AST node.
715724
#[derive(Debug, HashStable_Generic)]
716725
pub struct OwnerInfo<'hir> {
@@ -728,10 +737,39 @@ pub struct OwnerInfo<'hir> {
728737
impl<'tcx> OwnerInfo<'tcx> {
729738
#[inline]
730739
pub fn node(&self) -> OwnerNode<'tcx> {
731-
use rustc_index::vec::Idx;
732-
let node = self.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
733-
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
734-
node
740+
self.nodes.node()
741+
}
742+
}
743+
744+
#[derive(Copy, Clone, Debug, HashStable_Generic)]
745+
pub enum MaybeOwner<T> {
746+
Owner(T),
747+
NonOwner(HirId),
748+
/// Used as a placeholder for unused LocalDefId.
749+
Phantom,
750+
}
751+
752+
impl<T> MaybeOwner<T> {
753+
pub fn as_owner(self) -> Option<T> {
754+
match self {
755+
MaybeOwner::Owner(i) => Some(i),
756+
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
757+
}
758+
}
759+
760+
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> MaybeOwner<U> {
761+
match self {
762+
MaybeOwner::Owner(i) => MaybeOwner::Owner(f(i)),
763+
MaybeOwner::NonOwner(hir_id) => MaybeOwner::NonOwner(hir_id),
764+
MaybeOwner::Phantom => MaybeOwner::Phantom,
765+
}
766+
}
767+
768+
pub fn unwrap(self) -> T {
769+
match self {
770+
MaybeOwner::Owner(i) => i,
771+
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => panic!("Not a HIR owner"),
772+
}
735773
}
736774
}
737775

@@ -743,7 +781,7 @@ impl<'tcx> OwnerInfo<'tcx> {
743781
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
744782
#[derive(Debug)]
745783
pub struct Crate<'hir> {
746-
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
784+
pub owners: IndexVec<LocalDefId, MaybeOwner<&'hir OwnerInfo<'hir>>>,
747785
pub hir_hash: Fingerprint,
748786
}
749787

compiler/rustc_hir/src/hir_id.rs

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ impl HirId {
3030
if self.local_id.index() == 0 { Some(self.owner) } else { None }
3131
}
3232

33+
#[inline]
34+
pub fn is_owner(self) -> bool {
35+
self.local_id.index() == 0
36+
}
37+
3338
#[inline]
3439
pub fn make_owner(owner: LocalDefId) -> Self {
3540
Self { owner, local_id: ItemLocalId::from_u32(0) }

compiler/rustc_middle/src/hir/map/mod.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl<'hir> Map<'hir> {
162162

163163
pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
164164
let krate = self.krate();
165-
krate.owners.iter().filter_map(|owner| match owner.as_ref()?.node() {
165+
krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() {
166166
OwnerNode::Item(item) => Some(item),
167167
_ => None,
168168
})
@@ -205,7 +205,8 @@ impl<'hir> Map<'hir> {
205205
Some(hir_id.owner)
206206
} else {
207207
self.tcx
208-
.hir_owner_nodes(hir_id.owner)?
208+
.hir_owner_nodes(hir_id.owner)
209+
.as_owner()?
209210
.local_id_to_def_id
210211
.get(&hir_id.local_id)
211212
.copied()
@@ -214,8 +215,7 @@ impl<'hir> Map<'hir> {
214215

215216
#[inline]
216217
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
217-
// FIXME(#85914) is this access safe for incr. comp.?
218-
self.tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id)
218+
self.tcx.local_def_id_to_hir_id(def_id)
219219
}
220220

221221
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
@@ -321,7 +321,7 @@ impl<'hir> Map<'hir> {
321321
if id.local_id == ItemLocalId::from_u32(0) {
322322
Some(self.tcx.hir_owner_parent(id.owner))
323323
} else {
324-
let owner = self.tcx.hir_owner_nodes(id.owner)?;
324+
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
325325
let node = owner.nodes[id.local_id].as_ref()?;
326326
let hir_id = HirId { owner: id.owner, local_id: node.parent };
327327
Some(hir_id)
@@ -338,7 +338,7 @@ impl<'hir> Map<'hir> {
338338
let owner = self.tcx.hir_owner(id.owner)?;
339339
Some(owner.node.into())
340340
} else {
341-
let owner = self.tcx.hir_owner_nodes(id.owner)?;
341+
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
342342
let node = owner.nodes[id.local_id].as_ref()?;
343343
Some(node.node)
344344
}
@@ -522,7 +522,7 @@ impl<'hir> Map<'hir> {
522522
.owners
523523
.iter_enumerated()
524524
.flat_map(move |(owner, owner_info)| {
525-
let bodies = &owner_info.as_ref()?.nodes.bodies;
525+
let bodies = &owner_info.as_owner()?.nodes.bodies;
526526
Some(bodies.iter().map(move |&(local_id, _)| {
527527
let hir_id = HirId { owner, local_id };
528528
let body_id = BodyId { hir_id };
@@ -539,7 +539,7 @@ impl<'hir> Map<'hir> {
539539

540540
par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| {
541541
let owner = LocalDefId::new(owner);
542-
if let Some(owner_info) = owner_info {
542+
if let MaybeOwner::Owner(owner_info) = owner_info {
543543
par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| {
544544
let hir_id = HirId { owner, local_id: *local_id };
545545
let body_id = BodyId { hir_id };
@@ -601,7 +601,7 @@ impl<'hir> Map<'hir> {
601601
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
602602
let krate = self.krate();
603603
for (owner, info) in krate.owners.iter_enumerated() {
604-
if let Some(info) = info {
604+
if let MaybeOwner::Owner(info) = info {
605605
for (local_id, attrs) in info.attrs.map.iter() {
606606
let id = HirId { owner, local_id: *local_id };
607607
for a in *attrs {
@@ -625,7 +625,7 @@ impl<'hir> Map<'hir> {
625625
V: itemlikevisit::ItemLikeVisitor<'hir>,
626626
{
627627
let krate = self.krate();
628-
for owner in krate.owners.iter().filter_map(Option::as_ref) {
628+
for owner in krate.owners.iter().filter_map(|i| i.as_owner()) {
629629
match owner.node() {
630630
OwnerNode::Item(item) => visitor.visit_item(item),
631631
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
@@ -642,12 +642,14 @@ impl<'hir> Map<'hir> {
642642
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
643643
{
644644
let krate = self.krate();
645-
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(OwnerInfo::node) {
646-
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
647-
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
648-
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
649-
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
650-
Some(OwnerNode::Crate(_)) | None => {}
645+
par_for_each_in(&krate.owners.raw, |owner| match owner.map(OwnerInfo::node) {
646+
MaybeOwner::Owner(OwnerNode::Item(item)) => visitor.visit_item(item),
647+
MaybeOwner::Owner(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
648+
MaybeOwner::Owner(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
649+
MaybeOwner::Owner(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
650+
MaybeOwner::Owner(OwnerNode::Crate(_))
651+
| MaybeOwner::NonOwner(_)
652+
| MaybeOwner::Phantom => {}
651653
})
652654
}
653655

@@ -1121,7 +1123,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
11211123
.owners
11221124
.iter_enumerated()
11231125
.filter_map(|(def_id, info)| {
1124-
let _ = info.as_ref()?;
1126+
let _ = info.as_owner()?;
11251127
let def_path_hash = definitions.def_path_hash(def_id);
11261128
let span = definitions.def_span(def_id);
11271129
debug_assert_eq!(span.parent(), None);

0 commit comments

Comments
 (0)