Skip to content

Commit b9161ab

Browse files
committed
Do not use DUMMY_HIR_ID as placeholder value in node_id_to_hir_id table
Some helpers functions have been introduced to deal with (buggy) cases where either a `NodeId` or a `DefId` do not have a corresponding `HirId`. Those cases are tracked in issue #71104.
1 parent 513a647 commit b9161ab

File tree

7 files changed

+66
-30
lines changed

7 files changed

+66
-30
lines changed

src/librustc_ast_lowering/lib.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ struct LoweringContext<'a, 'hir: 'a> {
168168

169169
current_hir_id_owner: Vec<(LocalDefId, u32)>,
170170
item_local_id_counters: NodeMap<u32>,
171-
node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
171+
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
172172

173173
allow_try_trait: Option<Lrc<[Symbol]>>,
174174
allow_gen_future: Option<Lrc<[Symbol]>>,
@@ -522,15 +522,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
522522
}
523523

524524
self.lower_node_id(CRATE_NODE_ID);
525-
debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
525+
debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));
526526

527527
visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c);
528528
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
529529

530530
let module = self.lower_mod(&c.module);
531531
let attrs = self.lower_attrs(&c.attrs);
532532
let body_ids = body_ids(&self.bodies);
533-
let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id]).collect();
533+
let proc_macros =
534+
c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
534535

535536
self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
536537

@@ -571,26 +572,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
571572
ast_node_id: NodeId,
572573
alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId,
573574
) -> hir::HirId {
574-
if ast_node_id == DUMMY_NODE_ID {
575-
return hir::DUMMY_HIR_ID;
576-
}
575+
assert_ne!(ast_node_id, DUMMY_NODE_ID);
577576

578577
let min_size = ast_node_id.as_usize() + 1;
579578

580579
if min_size > self.node_id_to_hir_id.len() {
581-
self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
580+
self.node_id_to_hir_id.resize(min_size, None);
582581
}
583582

584-
let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
585-
586-
if existing_hir_id == hir::DUMMY_HIR_ID {
583+
if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
584+
existing_hir_id
585+
} else {
587586
// Generate a new `HirId`.
588587
let hir_id = alloc_hir_id(self);
589-
self.node_id_to_hir_id[ast_node_id] = hir_id;
588+
self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
590589

591590
hir_id
592-
} else {
593-
existing_hir_id
594591
}
595592
}
596593

src/librustc_hir/definitions.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub struct Definitions {
8787
node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
8888
def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
8989

90-
pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
90+
pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, Option<hir::HirId>>,
9191
/// The reverse mapping of `node_id_to_hir_id`.
9292
pub(super) hir_id_to_node_id: FxHashMap<hir::HirId, ast::NodeId>,
9393

@@ -359,11 +359,22 @@ impl Definitions {
359359

360360
#[inline]
361361
pub fn node_id_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
362+
self.node_id_to_hir_id[node_id].unwrap()
363+
}
364+
365+
#[inline]
366+
pub fn opt_node_id_to_hir_id(&self, node_id: ast::NodeId) -> Option<hir::HirId> {
362367
self.node_id_to_hir_id[node_id]
363368
}
364369

365370
#[inline]
366371
pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId {
372+
let node_id = self.def_id_to_node_id[id];
373+
self.node_id_to_hir_id[node_id].unwrap()
374+
}
375+
376+
#[inline]
377+
pub fn opt_local_def_id_to_hir_id(&self, id: LocalDefId) -> Option<hir::HirId> {
367378
let node_id = self.def_id_to_node_id[id];
368379
self.node_id_to_hir_id[node_id]
369380
}
@@ -470,7 +481,10 @@ impl Definitions {
470481

471482
/// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
472483
/// AST to HIR lowering.
473-
pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec<ast::NodeId, hir::HirId>) {
484+
pub fn init_node_id_to_hir_id_mapping(
485+
&mut self,
486+
mapping: IndexVec<ast::NodeId, Option<hir::HirId>>,
487+
) {
474488
assert!(
475489
self.node_id_to_hir_id.is_empty(),
476490
"trying to initialize `NodeId` -> `HirId` mapping twice"
@@ -481,7 +495,7 @@ impl Definitions {
481495
self.hir_id_to_node_id = self
482496
.node_id_to_hir_id
483497
.iter_enumerated()
484-
.map(|(node_id, &hir_id)| (hir_id, node_id))
498+
.filter_map(|(node_id, &hir_id)| hir_id.map(|hir_id| (hir_id, node_id)))
485499
.collect();
486500
}
487501

src/librustc_middle/hir/map/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,21 @@ impl<'hir> Map<'hir> {
214214
self.tcx.definitions.node_id_to_hir_id(node_id)
215215
}
216216

217+
#[inline]
218+
pub fn opt_node_id_to_hir_id(&self, node_id: NodeId) -> Option<HirId> {
219+
self.tcx.definitions.opt_node_id_to_hir_id(node_id)
220+
}
221+
217222
#[inline]
218223
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
219224
self.tcx.definitions.local_def_id_to_hir_id(def_id)
220225
}
221226

227+
#[inline]
228+
pub fn opt_local_def_id_to_hir_id(&self, def_id: LocalDefId) -> Option<HirId> {
229+
self.tcx.definitions.opt_local_def_id_to_hir_id(def_id)
230+
}
231+
222232
pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
223233
let node = self.find(hir_id)?;
224234

src/librustc_middle/ty/context.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -1126,13 +1126,16 @@ impl<'tcx> TyCtxt<'tcx> {
11261126

11271127
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
11281128
for (k, v) in resolutions.trait_map {
1129-
let hir_id = definitions.node_id_to_hir_id(k);
1130-
let map = trait_map.entry(hir_id.owner).or_default();
1131-
let v = v
1132-
.into_iter()
1133-
.map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
1134-
.collect();
1135-
map.insert(hir_id.local_id, StableVec::new(v));
1129+
// FIXME(#71104) Should really be using just `node_id_to_hir_id` but
1130+
// some `NodeId` do not seem to have a corresponding HirId.
1131+
if let Some(hir_id) = definitions.opt_node_id_to_hir_id(k) {
1132+
let map = trait_map.entry(hir_id.owner).or_default();
1133+
let v = v
1134+
.into_iter()
1135+
.map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
1136+
.collect();
1137+
map.insert(hir_id.local_id, StableVec::new(v));
1138+
}
11361139
}
11371140

11381141
GlobalCtxt {

src/librustc_privacy/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
928928

929929
let macro_module_def_id =
930930
ty::DefIdTree::parent(self.tcx, self.tcx.hir().local_def_id(md.hir_id)).unwrap();
931-
let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) {
931+
// FIXME(#71104) Should really be using just `as_local_hir_id` but
932+
// some `DefId` do not seem to have a corresponding HirId.
933+
let hir_id = macro_module_def_id
934+
.as_local()
935+
.and_then(|def_id| self.tcx.hir().opt_local_def_id_to_hir_id(def_id));
936+
let mut module_id = match hir_id {
932937
Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
933938
// `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
934939
_ => return,

src/librustc_save_analysis/dump_visitor.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,14 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
225225
collector.visit_pat(&arg.pat);
226226

227227
for (id, ident, ..) in collector.collected_idents {
228-
let hir_id = self.tcx.hir().node_id_to_hir_id(id);
229-
let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
230-
Some(s) => s.to_string(),
231-
None => continue,
232-
};
228+
// FIXME(#71104) Should really be using just `node_id_to_hir_id` but
229+
// some `NodeId` do not seem to have a corresponding HirId.
230+
let hir_id = self.tcx.hir().opt_node_id_to_hir_id(id);
231+
let typ =
232+
match hir_id.and_then(|hir_id| self.save_ctxt.tables.node_type_opt(hir_id)) {
233+
Some(s) => s.to_string(),
234+
None => continue,
235+
};
233236
if !self.span.filter_generated(ident.span) {
234237
let id = id_from_node_id(id, &self.save_ctxt);
235238
let span = self.span_from_span(ident.span);

src/librustc_typeck/check/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,11 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
838838
return tcx.has_typeck_tables(outer_def_id);
839839
}
840840

841-
if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
841+
// FIXME(#71104) Should really be using just `as_local_hir_id` but
842+
// some `LocalDefId` do not seem to have a corresponding HirId.
843+
if let Some(id) =
844+
def_id.as_local().and_then(|def_id| tcx.hir().opt_local_def_id_to_hir_id(def_id))
845+
{
842846
primary_body_of(tcx, id).is_some()
843847
} else {
844848
false

0 commit comments

Comments
 (0)