Skip to content

Commit e46e3e7

Browse files
committed
hir: Introduce TyCtxt::parent_hir_{id,node}
Remove the FIXME and keep `CRATE_HIR_ID` being its own parent. This scheme turned out to be more practical than having an `Option` on closer inspection. Also make `hir_owner_parent` more readable.
1 parent 68125c7 commit e46e3e7

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

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

+26-21
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,28 @@ impl<'tcx> TyCtxt<'tcx> {
175175
self.opt_hir_node_by_def_id(id)
176176
.unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}"))
177177
}
178+
179+
/// Returns `HirId` of the parent HIR node of node with this `hir_id`.
180+
/// Returns the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`.
181+
///
182+
/// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
183+
pub fn parent_hir_id(self, hir_id: HirId) -> HirId {
184+
let HirId { owner, local_id } = hir_id;
185+
if local_id == ItemLocalId::from_u32(0) {
186+
self.hir_owner_parent(owner)
187+
} else {
188+
let parent_local_id = self.hir_owner_nodes(owner).nodes[local_id].parent;
189+
// HIR indexing should have checked that.
190+
debug_assert_ne!(parent_local_id, local_id);
191+
HirId { owner, local_id: parent_local_id }
192+
}
193+
}
194+
195+
/// Returns parent HIR node of node with this `hir_id`.
196+
/// Returns HIR node of the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`.
197+
pub fn parent_hir_node(self, hir_id: HirId) -> Node<'tcx> {
198+
self.hir_node(self.parent_hir_id(hir_id))
199+
}
178200
}
179201

180202
impl<'hir> Map<'hir> {
@@ -217,37 +239,20 @@ impl<'hir> Map<'hir> {
217239
self.tcx.definitions_untracked().def_path_hash(def_id)
218240
}
219241

220-
/// Finds the id of the parent node to this one.
221-
///
222-
/// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
223242
pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
224-
if id.local_id == ItemLocalId::from_u32(0) {
225-
// FIXME: This function never returns `None` right now, and the parent chain end is
226-
// determined by checking for `parent(id) == id`. This function should return `None`
227-
// for the crate root instead.
228-
Some(self.tcx.hir_owner_parent(id.owner))
229-
} else {
230-
let owner = self.tcx.hir_owner_nodes(id.owner);
231-
let node = &owner.nodes[id.local_id];
232-
let hir_id = HirId { owner: id.owner, local_id: node.parent };
233-
// HIR indexing should have checked that.
234-
debug_assert_ne!(id.local_id, node.parent);
235-
Some(hir_id)
236-
}
243+
Some(self.tcx.parent_hir_id(id))
237244
}
238245

239-
#[track_caller]
240246
pub fn parent_id(self, hir_id: HirId) -> HirId {
241-
self.opt_parent_id(hir_id)
242-
.unwrap_or_else(|| bug!("No parent for node {}", self.node_to_string(hir_id)))
247+
self.tcx.parent_hir_id(hir_id)
243248
}
244249

245250
pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
246-
self.tcx.hir_node(self.parent_id(hir_id))
251+
self.tcx.parent_hir_node(hir_id)
247252
}
248253

249254
pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
250-
Some(self.tcx.hir_node(self.opt_parent_id(hir_id)?))
255+
Some(self.tcx.parent_hir_node(hir_id))
251256
}
252257

253258
pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {

compiler/rustc_middle/src/hir/mod.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,14 @@ pub fn provide(providers: &mut Providers) {
136136
};
137137
providers.opt_hir_owner_nodes =
138138
|tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
139-
providers.hir_owner_parent = |tcx, id| {
140-
// Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash.
141-
tcx.opt_local_parent(id.def_id).map_or(CRATE_HIR_ID, |parent| {
142-
let mut parent_hir_id = tcx.local_def_id_to_hir_id(parent);
143-
parent_hir_id.local_id =
144-
tcx.hir_crate(()).owners[parent_hir_id.owner.def_id].unwrap().parenting[&id.def_id];
145-
parent_hir_id
139+
providers.hir_owner_parent = |tcx, owner_id| {
140+
tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
141+
let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
142+
HirId {
143+
owner: parent_owner_id,
144+
local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id].unwrap().parenting
145+
[&owner_id.def_id],
146+
}
146147
})
147148
};
148149
providers.hir_attrs = |tcx, id| {

0 commit comments

Comments
 (0)