Skip to content

Commit 70ad73b

Browse files
committed
Make node_id_to_hir_id owner-local.
1 parent 2a0ed1f commit 70ad73b

File tree

3 files changed

+51
-39
lines changed

3 files changed

+51
-39
lines changed

compiler/rustc_ast_lowering/src/item.rs

-4
Original file line numberDiff line numberDiff line change
@@ -475,10 +475,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
475475
res
476476
} else {
477477
// Associate an HirId to both ids even if there is no resolution.
478-
let _old = self
479-
.node_id_to_hir_id
480-
.insert(new_node_id, hir::HirId::make_owner(new_id));
481-
debug_assert!(_old.is_none());
482478
self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
483479
let _old = std::mem::replace(
484480
&mut self.owners[new_id],

compiler/rustc_ast_lowering/src/lib.rs

+38-35
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use rustc_ast::{self as ast, *};
4242
use rustc_ast_pretty::pprust;
4343
use rustc_data_structures::captures::Captures;
4444
use rustc_data_structures::fingerprint::Fingerprint;
45-
use rustc_data_structures::fx::FxHashSet;
45+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4646
use rustc_data_structures::sorted_map::SortedMap;
4747
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4848
use rustc_data_structures::sync::Lrc;
@@ -65,6 +65,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
6565
use rustc_span::{Span, DUMMY_SP};
6666

6767
use smallvec::SmallVec;
68+
use std::collections::hash_map::Entry;
6869
use tracing::{debug, trace};
6970

7071
macro_rules! arena_vec {
@@ -152,10 +153,9 @@ struct LoweringContext<'a, 'hir: 'a> {
152153

153154
current_hir_id_owner: LocalDefId,
154155
item_local_id_counter: hir::ItemLocalId,
155-
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
156156

157157
/// NodeIds that are lowered inside the current HIR owner.
158-
local_node_ids: Vec<NodeId>,
158+
node_id_to_local_id: FxHashMap<NodeId, hir::ItemLocalId>,
159159

160160
allow_try_trait: Option<Lrc<[Symbol]>>,
161161
allow_gen_future: Option<Lrc<[Symbol]>>,
@@ -309,8 +309,7 @@ pub fn lower_crate<'a, 'hir>(
309309
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
310310
current_hir_id_owner: CRATE_DEF_ID,
311311
item_local_id_counter: hir::ItemLocalId::new(0),
312-
node_id_to_hir_id: IndexVec::new(),
313-
local_node_ids: Vec::new(),
312+
node_id_to_local_id: FxHashMap::default(),
314313
generator_kind: None,
315314
task_context: None,
316315
current_item: None,
@@ -437,23 +436,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
437436

438437
let current_attrs = std::mem::take(&mut self.attrs);
439438
let current_bodies = std::mem::take(&mut self.bodies);
440-
let current_node_ids = std::mem::take(&mut self.local_node_ids);
439+
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
441440
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
442441
let current_local_counter =
443442
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
444443

445444
// Always allocate the first `HirId` for the owner itself.
446-
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
445+
let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
447446
debug_assert_eq!(_old, None);
448-
self.local_node_ids.push(owner);
449447

450448
let item = f(self);
451449
debug_assert_eq!(def_id, item.def_id());
452450
let info = self.make_owner_info(item);
453451

454452
self.attrs = current_attrs;
455453
self.bodies = current_bodies;
456-
self.local_node_ids = current_node_ids;
454+
self.node_id_to_local_id = current_node_ids;
457455
self.current_hir_id_owner = current_owner;
458456
self.item_local_id_counter = current_local_counter;
459457

@@ -466,34 +464,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
466464
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
467465
let attrs = std::mem::take(&mut self.attrs);
468466
let mut bodies = std::mem::take(&mut self.bodies);
469-
let local_node_ids = std::mem::take(&mut self.local_node_ids);
467+
let node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
470468

471-
let local_id_to_def_id = local_node_ids
469+
let local_id_to_def_id = node_id_to_local_id
472470
.iter()
473-
.filter_map(|&node_id| {
471+
.filter_map(|(&node_id, &local_id)| {
474472
let def_id = self.resolver.opt_local_def_id(node_id)?;
475-
let hir_id = self.node_id_to_hir_id[node_id]?;
476473

477474
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
478475
if let o @ hir::MaybeOwner::Phantom = &mut self.owners[def_id] {
479476
// Do not override a `MaybeOwner::Owner` that may already here.
477+
let hir_id = hir::HirId { owner: self.current_hir_id_owner, local_id };
480478
*o = hir::MaybeOwner::NonOwner(hir_id);
481479
}
482480

483-
if hir_id.local_id == hir::ItemLocalId::new(0) {
484-
None
485-
} else {
486-
Some((hir_id.local_id, def_id))
487-
}
481+
if local_id == hir::ItemLocalId::new(0) { None } else { Some((local_id, def_id)) }
488482
})
489483
.collect();
490484

491-
let trait_map = local_node_ids
485+
let trait_map = node_id_to_local_id
492486
.into_iter()
493-
.filter_map(|node_id| {
494-
let hir_id = self.node_id_to_hir_id[node_id]?;
487+
.filter_map(|(node_id, local_id)| {
495488
let traits = self.resolver.take_trait_map(node_id)?;
496-
Some((hir_id.local_id, traits.into_boxed_slice()))
489+
Some((local_id, traits.into_boxed_slice()))
497490
})
498491
.collect();
499492

@@ -558,14 +551,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
558551
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
559552
assert_ne!(ast_node_id, DUMMY_NODE_ID);
560553

561-
*self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
562-
// Generate a new `HirId`.
563-
let owner = self.current_hir_id_owner;
564-
let local_id = self.item_local_id_counter;
565-
self.item_local_id_counter.increment_by(1);
566-
self.local_node_ids.push(ast_node_id);
567-
hir::HirId { owner, local_id }
568-
})
554+
let owner = self.current_hir_id_owner;
555+
let local_id = match self.node_id_to_local_id.entry(ast_node_id) {
556+
Entry::Occupied(o) => *o.get(),
557+
Entry::Vacant(v) => {
558+
// Generate a new `HirId`.
559+
let local_id = self.item_local_id_counter;
560+
self.item_local_id_counter.increment_by(1);
561+
v.insert(local_id);
562+
local_id
563+
}
564+
};
565+
hir::HirId { owner, local_id }
569566
}
570567

571568
fn next_id(&mut self) -> hir::HirId {
@@ -574,11 +571,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
574571
}
575572

576573
fn lower_res(&mut self, res: Res<NodeId>) -> Res {
577-
res.map_id(|id| {
578-
self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| {
579-
panic!("expected `NodeId` to be lowered already for res {:#?}", res);
580-
})
581-
})
574+
let res: Result<Res, ()> = res.apply_id(|id| {
575+
let owner = self.current_hir_id_owner;
576+
let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?;
577+
Ok(hir::HirId { owner, local_id })
578+
});
579+
// We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
580+
// This can happen when trying to lower the return type `x` in erroneous code like
581+
// async fn foo(x: u8) -> x {}
582+
// In that case, `x` is lowered as a function parameter, and the return type is lowered as
583+
// an opaque type as a synthetized HIR owner.
584+
res.unwrap_or(Res::Err)
582585
}
583586

584587
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {

compiler/rustc_hir/src/def.rs

+13
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,19 @@ impl<Id> Res<Id> {
603603
}
604604
}
605605

606+
pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
607+
Ok(match self {
608+
Res::Def(kind, id) => Res::Def(kind, id),
609+
Res::SelfCtor(id) => Res::SelfCtor(id),
610+
Res::PrimTy(id) => Res::PrimTy(id),
611+
Res::Local(id) => Res::Local(map(id)?),
612+
Res::SelfTy(a, b) => Res::SelfTy(a, b),
613+
Res::ToolMod => Res::ToolMod,
614+
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
615+
Res::Err => Res::Err,
616+
})
617+
}
618+
606619
#[track_caller]
607620
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
608621
self.map_id(|_| panic!("unexpected `Res::Local`"))

0 commit comments

Comments
 (0)