Get rid of the hir_owner query.

This commit is contained in:
Camille GILLOT 2024-01-15 22:31:02 +00:00
parent 92f2e0aa62
commit b99c3ae6d6
7 changed files with 42 additions and 77 deletions

View File

@ -841,7 +841,7 @@ pub struct OwnerNodes<'tcx> {
} }
impl<'tcx> OwnerNodes<'tcx> { impl<'tcx> OwnerNodes<'tcx> {
fn node(&self) -> OwnerNode<'tcx> { pub fn node(&self) -> OwnerNode<'tcx> {
use rustc_index::Idx; use rustc_index::Idx;
let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node; let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode. let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.

View File

@ -128,9 +128,11 @@ impl<'tcx> IfThisChanged<'tcx> {
if attr.has_name(sym::rustc_if_this_changed) { if attr.has_name(sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr); let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned { let dep_node = match dep_node_interned {
None => { None => DepNode::from_def_path_hash(
DepNode::from_def_path_hash(self.tcx, def_path_hash, dep_kinds::hir_owner) self.tcx,
} def_path_hash,
dep_kinds::hir_owner_nodes,
),
Some(n) => { Some(n) => {
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) { match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
Ok(n) => n, Ok(n) => n,

View File

@ -57,8 +57,7 @@ const BASE_FN: &[&str] = &[
/// DepNodes for Hir, which is pretty much everything /// DepNodes for Hir, which is pretty much everything
const BASE_HIR: &[&str] = &[ const BASE_HIR: &[&str] = &[
// hir_owner and hir_owner_nodes should be computed for all nodes // hir_owner_nodes should be computed for all nodes
label_strs::hir_owner,
label_strs::hir_owner_nodes, label_strs::hir_owner_nodes,
]; ];

View File

@ -1,4 +1,4 @@
use crate::hir::{ModuleItems, Owner}; use crate::hir::ModuleItems;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate; use crate::query::LocalCrate;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
@ -108,7 +108,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
if self.current_id.local_id.index() != 0 { if self.current_id.local_id.index() != 0 {
self.current_id.local_id = ItemLocalId::new(0); self.current_id.local_id = ItemLocalId::new(0);
if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
return Some((self.current_id.owner, node.node)); return Some((self.current_id.owner, node));
} }
} }
if self.current_id == CRATE_HIR_ID { if self.current_id == CRATE_HIR_ID {
@ -126,23 +126,23 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
// If this `HirId` doesn't have an entry, skip it and look for its `parent_id`. // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`.
if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
return Some((self.current_id.owner, node.node)); return Some((self.current_id.owner, node));
} }
} }
} }
} }
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
#[inline]
fn hir_owner(self, owner: OwnerId) -> Option<OwnerNode<'tcx>> {
Some(self.hir_owner_nodes(owner).as_owner()?.node())
}
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found. /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> { pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
if id.local_id == ItemLocalId::from_u32(0) { let owner = self.hir_owner_nodes(id.owner).as_owner()?;
let owner = self.hir_owner(id.owner)?; let node = owner.nodes[id.local_id].as_ref()?;
Some(owner.node.into()) Some(node.node)
} else {
let owner = self.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
Some(node.node)
}
} }
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found. /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
@ -174,7 +174,7 @@ impl<'hir> Map<'hir> {
#[inline] #[inline]
pub fn root_module(self) -> &'hir Mod<'hir> { pub fn root_module(self) -> &'hir Mod<'hir> {
match self.tcx.hir_owner(CRATE_OWNER_ID).map(|o| o.node) { match self.tcx.hir_owner(CRATE_OWNER_ID) {
Some(OwnerNode::Crate(item)) => item, Some(OwnerNode::Crate(item)) => item,
_ => bug!(), _ => bug!(),
} }
@ -242,27 +242,27 @@ impl<'hir> Map<'hir> {
pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> { pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
let node = self.tcx.hir_owner(OwnerId { def_id: id })?; let node = self.tcx.hir_owner(OwnerId { def_id: id })?;
node.node.generics() node.generics()
} }
pub fn owner(self, id: OwnerId) -> OwnerNode<'hir> { pub fn owner(self, id: OwnerId) -> OwnerNode<'hir> {
self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id)).node self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id))
} }
pub fn item(self, id: ItemId) -> &'hir Item<'hir> { pub fn item(self, id: ItemId) -> &'hir Item<'hir> {
self.tcx.hir_owner(id.owner_id).unwrap().node.expect_item() self.tcx.hir_owner(id.owner_id).unwrap().expect_item()
} }
pub fn trait_item(self, id: TraitItemId) -> &'hir TraitItem<'hir> { pub fn trait_item(self, id: TraitItemId) -> &'hir TraitItem<'hir> {
self.tcx.hir_owner(id.owner_id).unwrap().node.expect_trait_item() self.tcx.hir_owner(id.owner_id).unwrap().expect_trait_item()
} }
pub fn impl_item(self, id: ImplItemId) -> &'hir ImplItem<'hir> { pub fn impl_item(self, id: ImplItemId) -> &'hir ImplItem<'hir> {
self.tcx.hir_owner(id.owner_id).unwrap().node.expect_impl_item() self.tcx.hir_owner(id.owner_id).unwrap().expect_impl_item()
} }
pub fn foreign_item(self, id: ForeignItemId) -> &'hir ForeignItem<'hir> { pub fn foreign_item(self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
self.tcx.hir_owner(id.owner_id).unwrap().node.expect_foreign_item() self.tcx.hir_owner(id.owner_id).unwrap().expect_foreign_item()
} }
pub fn body(self, id: BodyId) -> &'hir Body<'hir> { pub fn body(self, id: BodyId) -> &'hir Body<'hir> {
@ -436,7 +436,7 @@ impl<'hir> Map<'hir> {
pub fn get_module(self, module: LocalModDefId) -> (&'hir Mod<'hir>, Span, HirId) { pub fn get_module(self, module: LocalModDefId) -> (&'hir Mod<'hir>, Span, HirId) {
let hir_id = HirId::make_owner(module.to_local_def_id()); let hir_id = HirId::make_owner(module.to_local_def_id());
match self.tcx.hir_owner(hir_id.owner).map(|o| o.node) { match self.tcx.hir_owner(hir_id.owner) {
Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. })) => (m, span, hir_id), Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. })) => (m, span, hir_id),
Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id), Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id),
node => panic!("not a module: {node:?}"), node => panic!("not a module: {node:?}"),
@ -726,11 +726,10 @@ impl<'hir> Map<'hir> {
pub fn get_foreign_abi(self, hir_id: HirId) -> Abi { pub fn get_foreign_abi(self, hir_id: HirId) -> Abi {
let parent = self.get_parent_item(hir_id); let parent = self.get_parent_item(hir_id);
if let Some(node) = self.tcx.hir_owner(parent) { if let Some(node) = self.tcx.hir_owner(parent)
if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node && let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node
{ {
return *abi; return *abi;
}
} }
bug!( bug!(
"expected foreign mod or inlined parent, found {}", "expected foreign mod or inlined parent, found {}",
@ -742,33 +741,32 @@ impl<'hir> Map<'hir> {
self.tcx self.tcx
.hir_owner(OwnerId { def_id }) .hir_owner(OwnerId { def_id })
.unwrap_or_else(|| bug!("expected owner for {:?}", def_id)) .unwrap_or_else(|| bug!("expected owner for {:?}", def_id))
.node
} }
pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> {
match self.tcx.hir_owner(OwnerId { def_id: id }) { match self.tcx.hir_owner(OwnerId { def_id: id }) {
Some(Owner { node: OwnerNode::Item(item), .. }) => item, Some(OwnerNode::Item(item)) => item,
_ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))),
} }
} }
pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> { pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> {
match self.tcx.hir_owner(OwnerId { def_id: id }) { match self.tcx.hir_owner(OwnerId { def_id: id }) {
Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item, Some(OwnerNode::ImplItem(item)) => item,
_ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))),
} }
} }
pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> { pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> {
match self.tcx.hir_owner(OwnerId { def_id: id }) { match self.tcx.hir_owner(OwnerId { def_id: id }) {
Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item, Some(OwnerNode::TraitItem(item)) => item,
_ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))),
} }
} }
pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> { pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> {
match self.tcx.hir_owner(OwnerId { def_id }) { match self.tcx.hir_owner(OwnerId { def_id }) {
Some(Owner { node, .. }) => node.fn_decl().map(|fn_decl| &fn_decl.output), Some(node) => node.fn_decl().map(|fn_decl| &fn_decl.output),
_ => None, _ => None,
} }
} }
@ -782,7 +780,7 @@ impl<'hir> Map<'hir> {
pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> { pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> {
match self.tcx.hir_owner(id) { match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item, Some(OwnerNode::ForeignItem(item)) => item,
_ => { _ => {
bug!( bug!(
"expected foreign item, found {}", "expected foreign item, found {}",

View File

@ -8,34 +8,12 @@ pub mod place;
use crate::query::Providers; use crate::query::Providers;
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt}; use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync}; use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::*; use rustc_hir::*;
use rustc_query_system::ich::StableHashingContext;
use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP}; use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP};
/// Top-level HIR node for current owner. This only contains the node for which
/// `HirId::local_id == 0`, and excludes bodies.
///
/// This struct exists to encapsulate all access to the hir_owner query in this module, and to
/// implement HashStable without hashing bodies.
#[derive(Copy, Clone, Debug)]
pub struct Owner<'tcx> {
node: OwnerNode<'tcx>,
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> {
#[inline]
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
// Perform a shallow hash instead using the deep hash saved in `OwnerNodes`. This lets us
// differentiate queries that depend on the full HIR tree from those that only depend on
// the item signature.
hcx.without_hir_bodies(|hcx| self.node.hash_stable(hcx, hasher));
}
}
/// Gather the LocalDefId for each item-like within a module, including items contained within /// Gather the LocalDefId for each item-like within a module, including items contained within
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules. /// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
#[derive(Debug, HashStable, Encodable, Decodable)] #[derive(Debug, HashStable, Encodable, Decodable)]
@ -149,11 +127,6 @@ pub fn provide(providers: &mut Providers) {
providers.hir_crate_items = map::hir_crate_items; providers.hir_crate_items = map::hir_crate_items;
providers.crate_hash = map::crate_hash; providers.crate_hash = map::crate_hash;
providers.hir_module_items = map::hir_module_items; providers.hir_module_items = map::hir_module_items;
providers.hir_owner = |tcx, id| {
let owner = tcx.hir_crate(()).owners.get(id.def_id)?.as_owner()?;
let node = owner.node();
Some(Owner { node })
};
providers.opt_local_def_id_to_hir_id = |tcx, id| { providers.opt_local_def_id_to_hir_id = |tcx, id| {
let owner = tcx.hir_crate(()).owners[id].map(|_| ()); let owner = tcx.hir_crate(()).owners[id].map(|_| ());
Some(match owner { Some(match owner {
@ -162,7 +135,13 @@ pub fn provide(providers: &mut Providers) {
MaybeOwner::NonOwner(hir_id) => hir_id, MaybeOwner::NonOwner(hir_id) => hir_id,
}) })
}; };
providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id.def_id].map(|i| &i.nodes); providers.hir_owner_nodes = |tcx, id| {
if let Some(i) = tcx.hir_crate(()).owners.get(id.def_id) {
i.map(|i| &i.nodes)
} else {
MaybeOwner::Phantom
}
};
providers.hir_owner_parent = |tcx, id| { providers.hir_owner_parent = |tcx, id| {
// Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash. // Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash.
tcx.opt_local_parent(id.def_id).map_or(CRATE_HIR_ID, |parent| { tcx.opt_local_parent(id.def_id).map_or(CRATE_HIR_ID, |parent| {

View File

@ -160,10 +160,6 @@ impl<T> EraseType for Option<&'_ [T]> {
type Result = [u8; size_of::<Option<&'static [()]>>()]; type Result = [u8; size_of::<Option<&'static [()]>>()];
} }
impl EraseType for Option<rustc_middle::hir::Owner<'_>> {
type Result = [u8; size_of::<Option<rustc_middle::hir::Owner<'static>>>()];
}
impl EraseType for Option<mir::DestructuredConstant<'_>> { impl EraseType for Option<mir::DestructuredConstant<'_>> {
type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()]; type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
} }
@ -320,7 +316,6 @@ macro_rules! tcx_lifetime {
} }
tcx_lifetime! { tcx_lifetime! {
rustc_middle::hir::Owner,
rustc_middle::middle::exported_symbols::ExportedSymbol, rustc_middle::middle::exported_symbols::ExportedSymbol,
rustc_middle::mir::Const, rustc_middle::mir::Const,
rustc_middle::mir::DestructuredConstant, rustc_middle::mir::DestructuredConstant,

View File

@ -174,14 +174,6 @@ rustc_queries! {
cache_on_disk_if { true } cache_on_disk_if { true }
} }
/// Gives access to the HIR node for the HIR owner `key`.
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_owner(key: hir::OwnerId) -> Option<crate::hir::Owner<'tcx>> {
desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key) }
}
/// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any.
/// ///
/// Definitions that were generated with no HIR, would be fed to return `None`. /// Definitions that were generated with no HIR, would be fed to return `None`.