Skip to content

Commit 3ff6796

Browse files
committed
hir: Make sure all HirIds have corresponding HIR Nodes
1 parent 49d49eb commit 3ff6796

File tree

10 files changed

+79
-37
lines changed

10 files changed

+79
-37
lines changed

compiler/rustc_ast_lowering/src/index.rs

+36-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct NodeCollector<'a, 'hir> {
1515
bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
1616

1717
/// Outputs
18-
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
18+
nodes: IndexVec<ItemLocalId, ParentedNode<'hir>>,
1919
parenting: LocalDefIdMap<ItemLocalId>,
2020

2121
/// The parent of this node
@@ -29,16 +29,19 @@ pub(super) fn index_hir<'hir>(
2929
tcx: TyCtxt<'hir>,
3030
item: hir::OwnerNode<'hir>,
3131
bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
32-
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, LocalDefIdMap<ItemLocalId>) {
33-
let mut nodes = IndexVec::new();
32+
num_nodes: usize,
33+
) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
34+
let zero_id = ItemLocalId::new(0);
35+
let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
36+
let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
3437
// This node's parent should never be accessed: the owner's parent is computed by the
3538
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
3639
// used.
37-
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
40+
nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
3841
let mut collector = NodeCollector {
3942
tcx,
4043
owner: item.def_id(),
41-
parent_node: ItemLocalId::new(0),
44+
parent_node: zero_id,
4245
nodes,
4346
bodies,
4447
parenting: Default::default(),
@@ -54,6 +57,14 @@ pub(super) fn index_hir<'hir>(
5457
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
5558
};
5659

60+
for (local_id, node) in collector.nodes.iter_enumerated() {
61+
if let Node::Err(span) = node.node {
62+
let hir_id = HirId { owner: item.def_id(), local_id };
63+
let msg = format!("ID {hir_id} not encountered when visiting item HIR");
64+
tcx.dcx().span_delayed_bug(*span, msg);
65+
}
66+
}
67+
5768
(collector.nodes, collector.parenting)
5869
}
5970

@@ -88,7 +99,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
8899
}
89100
}
90101

91-
self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node });
102+
self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
92103
}
93104

94105
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@@ -348,4 +359,23 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
348359

349360
self.visit_nested_foreign_item(id);
350361
}
362+
363+
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
364+
match predicate {
365+
WherePredicate::BoundPredicate(pred) => {
366+
self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
367+
self.with_parent(pred.hir_id, |this| {
368+
intravisit::walk_where_predicate(this, predicate)
369+
})
370+
}
371+
_ => intravisit::walk_where_predicate(self, predicate),
372+
}
373+
}
374+
375+
fn visit_array_length(&mut self, len: &'hir ArrayLen) {
376+
match len {
377+
ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
378+
ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
379+
}
380+
}
351381
}

compiler/rustc_ast_lowering/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
674674
} else {
675675
(None, None)
676676
};
677-
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
677+
let num_nodes = self.item_local_id_counter.as_usize();
678+
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
678679
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
679680
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
680681

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
216216
if let Some(id) = placeholder.bound.kind.get_id()
217217
&& let Some(placeholder_id) = id.as_local()
218218
&& let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
219-
&& let Some(generics_impl) = hir.get_parent(gat_hir_id).generics()
219+
&& let Some(generics_impl) =
220+
hir.get_parent(hir.parent_id(gat_hir_id)).generics()
220221
{
221222
Some((gat_hir_id, generics_impl))
222223
} else {

compiler/rustc_hir/src/hir.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -835,17 +835,16 @@ pub struct OwnerNodes<'tcx> {
835835
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
836836
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
837837
// used.
838-
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
838+
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
839839
/// Content of local bodies.
840840
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
841841
}
842842

843843
impl<'tcx> OwnerNodes<'tcx> {
844844
pub fn node(&self) -> OwnerNode<'tcx> {
845845
use rustc_index::Idx;
846-
let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
847-
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
848-
node
846+
// Indexing must ensure it is an OwnerNode.
847+
self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
849848
}
850849
}
851850

@@ -860,9 +859,7 @@ impl fmt::Debug for OwnerNodes<'_> {
860859
.nodes
861860
.iter_enumerated()
862861
.map(|(id, parented_node)| {
863-
let parented_node = parented_node.as_ref().map(|node| node.parent);
864-
865-
debug_fn(move |f| write!(f, "({id:?}, {parented_node:?})"))
862+
debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
866863
})
867864
.collect::<Vec<_>>(),
868865
)
@@ -3357,13 +3354,15 @@ impl<'hir> OwnerNode<'hir> {
33573354
}
33583355
}
33593356

3360-
pub fn span(&self) -> Span {
3357+
// Span by reference to pass to `Node::Err`.
3358+
#[allow(rustc::pass_by_value)]
3359+
pub fn span(&self) -> &'hir Span {
33613360
match self {
33623361
OwnerNode::Item(Item { span, .. })
33633362
| OwnerNode::ForeignItem(ForeignItem { span, .. })
33643363
| OwnerNode::ImplItem(ImplItem { span, .. })
3365-
| OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
3366-
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
3364+
| OwnerNode::TraitItem(TraitItem { span, .. }) => span,
3365+
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
33673366
}
33683367
}
33693368

@@ -3492,17 +3491,18 @@ pub enum Node<'hir> {
34923491
Arm(&'hir Arm<'hir>),
34933492
Block(&'hir Block<'hir>),
34943493
Local(&'hir Local<'hir>),
3495-
34963494
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
34973495
/// with synthesized constructors.
34983496
Ctor(&'hir VariantData<'hir>),
3499-
35003497
Lifetime(&'hir Lifetime),
35013498
GenericParam(&'hir GenericParam<'hir>),
3502-
35033499
Crate(&'hir Mod<'hir>),
3504-
35053500
Infer(&'hir InferArg),
3501+
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
3502+
ArrayLenInfer(&'hir InferArg),
3503+
// Span by reference to minimize `Node`'s size
3504+
#[allow(rustc::pass_by_value)]
3505+
Err(&'hir Span),
35063506
}
35073507

35083508
impl<'hir> Node<'hir> {
@@ -3547,7 +3547,10 @@ impl<'hir> Node<'hir> {
35473547
| Node::Crate(..)
35483548
| Node::Ty(..)
35493549
| Node::TraitRef(..)
3550-
| Node::Infer(..) => None,
3550+
| Node::Infer(..)
3551+
| Node::WhereBoundPredicate(..)
3552+
| Node::ArrayLenInfer(..)
3553+
| Node::Err(..) => None,
35513554
}
35523555
}
35533556

compiler/rustc_hir_analysis/src/collect/type_of.rs

+2
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
509509
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
510510
},
511511

512+
Node::ArrayLenInfer(_) => tcx.types.usize,
513+
512514
x => {
513515
bug!("unexpected sort of node in type_of(): {:?}", x);
514516
}

compiler/rustc_hir_pretty/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ impl<'a> State<'a> {
117117
Node::Ctor(..) => panic!("cannot print isolated Ctor"),
118118
Node::Local(a) => self.print_local_decl(a),
119119
Node::Crate(..) => panic!("cannot print Crate"),
120+
Node::WhereBoundPredicate(pred) => {
121+
self.print_formal_generic_params(pred.bound_generic_params);
122+
self.print_type(pred.bounded_ty);
123+
self.print_bounds(":", pred.bounds);
124+
}
125+
Node::ArrayLenInfer(_) => self.word("_"),
126+
Node::Err(_) => self.word("/*ERROR*/"),
120127
}
121128
}
122129
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10531053
if self.can_coerce(found, ty) {
10541054
if let Some(node) = self.tcx.opt_hir_node(fn_id)
10551055
&& let Some(owner_node) = node.as_owner()
1056-
&& let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
1056+
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
10571057
{
10581058
err.multipart_suggestion(
10591059
"you might have meant to return this value",

compiler/rustc_metadata/src/rmeta/encoder.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -1388,13 +1388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13881388
if should_encode_fn_sig(def_kind) {
13891389
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
13901390
}
1391-
// FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]`
1392-
// do not have corresponding HIR nodes, so some queries usually making sense for
1393-
// anonymous constants will not work on them and panic. It's not clear whether it
1394-
// can cause any observable issues or not.
1395-
let anon_const_without_hir = def_kind == DefKind::AnonConst
1396-
&& tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
1397-
if should_encode_generics(def_kind) && !anon_const_without_hir {
1391+
if should_encode_generics(def_kind) {
13981392
let g = tcx.generics_of(def_id);
13991393
record!(self.tables.generics_of[def_id] <- g);
14001394
record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
@@ -1408,7 +1402,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14081402
}
14091403
}
14101404
}
1411-
if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir {
1405+
if should_encode_type(tcx, local_id, def_kind) {
14121406
record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
14131407
}
14141408
if should_encode_constness(def_kind) {

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

+8-4
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,7 @@ impl<'tcx> TyCtxt<'tcx> {
159159

160160
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
161161
pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
162-
let owner = self.hir_owner_nodes(id.owner);
163-
let node = owner.nodes[id.local_id].as_ref()?;
164-
Some(node.node)
162+
Some(self.hir_owner_nodes(id.owner).nodes[id.local_id].node)
165163
}
166164

167165
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
@@ -233,7 +231,7 @@ impl<'hir> Map<'hir> {
233231
Some(self.tcx.hir_owner_parent(id.owner))
234232
} else {
235233
let owner = self.tcx.hir_owner_nodes(id.owner);
236-
let node = owner.nodes[id.local_id].as_ref()?;
234+
let node = &owner.nodes[id.local_id];
237235
let hir_id = HirId { owner: id.owner, local_id: node.parent };
238236
// HIR indexing should have checked that.
239237
debug_assert_ne!(id.local_id, node.parent);
@@ -994,6 +992,9 @@ impl<'hir> Map<'hir> {
994992
Node::Infer(i) => i.span,
995993
Node::Local(local) => local.span,
996994
Node::Crate(item) => item.spans.inner_span,
995+
Node::WhereBoundPredicate(pred) => pred.span,
996+
Node::ArrayLenInfer(inf) => inf.span,
997+
Node::Err(span) => *span,
997998
}
998999
}
9991000

@@ -1255,6 +1256,9 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
12551256
format!("{id} (generic_param {})", path_str(param.def_id))
12561257
}
12571258
Some(Node::Crate(..)) => String::from("(root_crate)"),
1259+
Some(Node::WhereBoundPredicate(_)) => node_str("where bound predicate"),
1260+
Some(Node::ArrayLenInfer(_)) => node_str("array len infer"),
1261+
Some(Node::Err(_)) => node_str("error"),
12581262
None => format!("{id} (unknown node)"),
12591263
}
12601264
}

src/tools/clippy/clippy_lints/src/min_ident_chars.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
9494
cx.tcx.opt_hir_node(hir_id)
9595
} else {
9696
let owner = cx.tcx.hir_owner_nodes(hir_id.owner);
97-
owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node)
97+
owner.nodes.get(hir_id.local_id).copied().map(|p| p.node)
9898
};
9999
let Some(node) = node else {
100100
return;

0 commit comments

Comments
 (0)