Skip to content

Commit 8ebec97

Browse files
committed
Auto merge of rust-lang#93438 - spastorino:node_id_to_hir_id_refactor, r=oli-obk
Node id to hir id refactor Related to rust-lang#89278 r? `@oli-obk`
2 parents 532d3cd + d82a7bc commit 8ebec97

File tree

3 files changed

+74
-59
lines changed

3 files changed

+74
-59
lines changed

compiler/rustc_ast_lowering/src/item.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
360360
// method, it will not be considered an in-band
361361
// lifetime to be added, but rather a reference to a
362362
// parent lifetime.
363-
let lowered_trait_def_id = self.lower_node_id(id).expect_owner();
363+
let lowered_trait_def_id = hir_id.expect_owner();
364364
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
365365
ast_generics,
366366
lowered_trait_def_id,
@@ -509,10 +509,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
509509
let new_id = self.resolver.local_def_id(new_node_id);
510510
let Some(res) = resolutions.next() else {
511511
// Associate an HirId to both ids even if there is no resolution.
512-
let _old = self
513-
.node_id_to_hir_id
514-
.insert(new_node_id, hir::HirId::make_owner(new_id));
515-
debug_assert!(_old.is_none());
516512
self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
517513
let _old = std::mem::replace(
518514
&mut self.owners[new_id],

compiler/rustc_ast_lowering/src/lib.rs

+60-54
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use rustc_ast::{self as ast, *};
4444
use rustc_ast_pretty::pprust;
4545
use rustc_data_structures::captures::Captures;
4646
use rustc_data_structures::fingerprint::Fingerprint;
47-
use rustc_data_structures::fx::FxHashSet;
47+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4848
use rustc_data_structures::sorted_map::SortedMap;
4949
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5050
use rustc_data_structures::sync::Lrc;
@@ -54,7 +54,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
5454
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
5555
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
5656
use rustc_hir::intravisit;
57-
use rustc_hir::{ConstArg, GenericArg, ParamName};
57+
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
5858
use rustc_index::vec::{Idx, IndexVec};
5959
use rustc_query_system::ich::StableHashingContext;
6060
use rustc_session::lint::LintBuffer;
@@ -67,6 +67,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
6767
use rustc_span::{Span, DUMMY_SP};
6868

6969
use smallvec::SmallVec;
70+
use std::collections::hash_map::Entry;
7071
use tracing::{debug, trace};
7172

7273
macro_rules! arena_vec {
@@ -154,10 +155,11 @@ struct LoweringContext<'a, 'hir: 'a> {
154155

155156
current_hir_id_owner: LocalDefId,
156157
item_local_id_counter: hir::ItemLocalId,
157-
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
158+
local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
159+
trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
158160

159161
/// NodeIds that are lowered inside the current HIR owner.
160-
local_node_ids: Vec<NodeId>,
162+
node_id_to_local_id: FxHashMap<NodeId, hir::ItemLocalId>,
161163

162164
allow_try_trait: Option<Lrc<[Symbol]>>,
163165
allow_gen_future: Option<Lrc<[Symbol]>>,
@@ -368,8 +370,9 @@ pub fn lower_crate<'a, 'hir>(
368370
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
369371
current_hir_id_owner: CRATE_DEF_ID,
370372
item_local_id_counter: hir::ItemLocalId::new(0),
371-
node_id_to_hir_id: IndexVec::new(),
372-
local_node_ids: Vec::new(),
373+
node_id_to_local_id: FxHashMap::default(),
374+
local_id_to_def_id: SortedMap::new(),
375+
trait_map: FxHashMap::default(),
373376
generator_kind: None,
374377
task_context: None,
375378
current_item: None,
@@ -496,23 +499,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
496499

497500
let current_attrs = std::mem::take(&mut self.attrs);
498501
let current_bodies = std::mem::take(&mut self.bodies);
499-
let current_node_ids = std::mem::take(&mut self.local_node_ids);
502+
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
503+
let current_id_to_def_id = std::mem::take(&mut self.local_id_to_def_id);
504+
let current_trait_map = std::mem::take(&mut self.trait_map);
500505
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
501506
let current_local_counter =
502507
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
503508

504509
// Always allocate the first `HirId` for the owner itself.
505-
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
510+
let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
506511
debug_assert_eq!(_old, None);
507-
self.local_node_ids.push(owner);
508512

509513
let item = f(self);
510514
debug_assert_eq!(def_id, item.def_id());
511515
let info = self.make_owner_info(item);
512516

513517
self.attrs = current_attrs;
514518
self.bodies = current_bodies;
515-
self.local_node_ids = current_node_ids;
519+
self.node_id_to_local_id = current_node_ids;
520+
self.local_id_to_def_id = current_id_to_def_id;
521+
self.trait_map = current_trait_map;
516522
self.current_hir_id_owner = current_owner;
517523
self.item_local_id_counter = current_local_counter;
518524

@@ -525,34 +531,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
525531
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
526532
let attrs = std::mem::take(&mut self.attrs);
527533
let mut bodies = std::mem::take(&mut self.bodies);
528-
let local_node_ids = std::mem::take(&mut self.local_node_ids);
529-
530-
let local_id_to_def_id = local_node_ids
531-
.iter()
532-
.filter_map(|&node_id| {
533-
let hir_id = self.node_id_to_hir_id[node_id]?;
534-
if hir_id.local_id == hir::ItemLocalId::new(0) {
535-
None
536-
} else {
537-
let def_id = self.resolver.opt_local_def_id(node_id)?;
538-
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
539-
if let o @ hir::MaybeOwner::Phantom = &mut self.owners[def_id] {
540-
// Do not override a `MaybeOwner::Owner` that may already here.
541-
*o = hir::MaybeOwner::NonOwner(hir_id);
542-
}
543-
Some((hir_id.local_id, def_id))
544-
}
545-
})
546-
.collect();
547-
548-
let trait_map = local_node_ids
549-
.into_iter()
550-
.filter_map(|node_id| {
551-
let hir_id = self.node_id_to_hir_id[node_id]?;
552-
let traits = self.resolver.take_trait_map(node_id)?;
553-
Some((hir_id.local_id, traits.into_boxed_slice()))
554-
})
555-
.collect();
556534

557535
#[cfg(debug_assertions)]
558536
for (id, attrs) in attrs.iter() {
@@ -572,7 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
572550
hash_without_bodies,
573551
nodes,
574552
bodies,
575-
local_id_to_def_id,
553+
local_id_to_def_id: std::mem::take(&mut self.local_id_to_def_id),
576554
};
577555
let attrs = {
578556
let mut hcx = self.resolver.create_stable_hashing_context();
@@ -582,7 +560,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
582560
hir::AttributeMap { map: attrs, hash }
583561
};
584562

585-
hir::OwnerInfo { nodes, parenting, attrs, trait_map }
563+
hir::OwnerInfo { nodes, parenting, attrs, trait_map: std::mem::take(&mut self.trait_map) }
586564
}
587565

588566
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
@@ -615,14 +593,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
615593
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
616594
assert_ne!(ast_node_id, DUMMY_NODE_ID);
617595

618-
*self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
619-
// Generate a new `HirId`.
620-
let owner = self.current_hir_id_owner;
621-
let local_id = self.item_local_id_counter;
622-
self.item_local_id_counter.increment_by(1);
623-
self.local_node_ids.push(ast_node_id);
624-
hir::HirId { owner, local_id }
625-
})
596+
match self.node_id_to_local_id.entry(ast_node_id) {
597+
Entry::Occupied(o) => {
598+
hir::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
599+
}
600+
Entry::Vacant(v) => {
601+
// Generate a new `HirId`.
602+
let owner = self.current_hir_id_owner;
603+
let local_id = self.item_local_id_counter;
604+
let hir_id = hir::HirId { owner, local_id };
605+
606+
v.insert(local_id);
607+
self.item_local_id_counter.increment_by(1);
608+
609+
assert_ne!(local_id, hir::ItemLocalId::new(0));
610+
if let Some(def_id) = self.resolver.opt_local_def_id(ast_node_id) {
611+
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
612+
if let o @ hir::MaybeOwner::Phantom = &mut self.owners[def_id] {
613+
// Do not override a `MaybeOwner::Owner` that may already here.
614+
*o = hir::MaybeOwner::NonOwner(hir_id);
615+
}
616+
self.local_id_to_def_id.insert(local_id, def_id);
617+
}
618+
619+
if let Some(traits) = self.resolver.take_trait_map(ast_node_id) {
620+
self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
621+
}
622+
623+
hir_id
624+
}
625+
}
626626
}
627627

628628
fn next_id(&mut self) -> hir::HirId {
@@ -631,11 +631,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
631631
}
632632

633633
fn lower_res(&mut self, res: Res<NodeId>) -> Res {
634-
res.map_id(|id| {
635-
self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| {
636-
panic!("expected `NodeId` to be lowered already for res {:#?}", res);
637-
})
638-
})
634+
let res: Result<Res, ()> = res.apply_id(|id| {
635+
let owner = self.current_hir_id_owner;
636+
let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?;
637+
Ok(hir::HirId { owner, local_id })
638+
});
639+
// We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
640+
// This can happen when trying to lower the return type `x` in erroneous code like
641+
// async fn foo(x: u8) -> x {}
642+
// In that case, `x` is lowered as a function parameter, and the return type is lowered as
643+
// an opaque type as a synthetized HIR owner.
644+
res.unwrap_or(Res::Err)
639645
}
640646

641647
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
@@ -1476,14 +1482,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14761482
let lifetime_defs =
14771483
lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(|&(name, span)| {
14781484
let def_node_id = lctx.resolver.next_node_id();
1479-
let hir_id = lctx.lower_node_id(def_node_id);
14801485
lctx.resolver.create_def(
14811486
opaque_ty_def_id,
14821487
def_node_id,
14831488
DefPathData::LifetimeNs(name.ident().name),
14841489
ExpnId::root(),
14851490
span.with_parent(None),
14861491
);
1492+
let hir_id = lctx.lower_node_id(def_node_id);
14871493

14881494
let (name, kind) = match name {
14891495
hir::LifetimeName::Underscore => (

compiler/rustc_hir/src/def.rs

+13
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,19 @@ impl<Id> Res<Id> {
611611
}
612612
}
613613

614+
pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
615+
Ok(match self {
616+
Res::Def(kind, id) => Res::Def(kind, id),
617+
Res::SelfCtor(id) => Res::SelfCtor(id),
618+
Res::PrimTy(id) => Res::PrimTy(id),
619+
Res::Local(id) => Res::Local(map(id)?),
620+
Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
621+
Res::ToolMod => Res::ToolMod,
622+
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
623+
Res::Err => Res::Err,
624+
})
625+
}
626+
614627
#[track_caller]
615628
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
616629
self.map_id(|_| panic!("unexpected `Res::Local`"))

0 commit comments

Comments
 (0)