Skip to content

Remove LocalDefId <-> HirId global maps #89278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -105,12 +105,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> T {
let old_len = self.in_scope_lifetimes.len();

let parent_generics =
match self.owners[parent_hir_id].as_ref().unwrap().node().expect_item().kind {
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
_ => &[],
};
let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind {
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
_ => &[],
};
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
_ => None,
@@ -476,10 +475,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
res
} else {
// Associate an HirId to both ids even if there is no resolution.
let _old = self
.node_id_to_hir_id
.insert(new_node_id, hir::HirId::make_owner(new_id));
debug_assert!(_old.is_none());
self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
let _old = std::mem::replace(
&mut self.owners[new_id],
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
);
debug_assert!(matches!(_old, hir::MaybeOwner::Phantom));
continue;
};
let ident = *ident;
104 changes: 51 additions & 53 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
@@ -65,6 +65,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};

use smallvec::SmallVec;
use std::collections::hash_map::Entry;
use tracing::{debug, trace};

macro_rules! arena_vec {
@@ -98,7 +99,7 @@ struct LoweringContext<'a, 'hir: 'a> {
arena: &'hir Arena<'hir>,

/// The items being lowered are collected here.
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
owners: IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
/// Bodies inside the owner being lowered.
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
/// Attributes inside the owner being lowered.
@@ -152,10 +153,9 @@ struct LoweringContext<'a, 'hir: 'a> {

current_hir_id_owner: LocalDefId,
item_local_id_counter: hir::ItemLocalId,
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,

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

allow_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>,
@@ -291,7 +291,8 @@ pub fn lower_crate<'a, 'hir>(
) -> &'hir hir::Crate<'hir> {
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");

let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count());
let owners =
IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, resolver.definitions().def_index_count());
LoweringContext {
sess,
resolver,
@@ -308,8 +309,7 @@ pub fn lower_crate<'a, 'hir>(
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
current_hir_id_owner: CRATE_DEF_ID,
item_local_id_counter: hir::ItemLocalId::new(0),
node_id_to_hir_id: IndexVec::new(),
local_node_ids: Vec::new(),
node_id_to_local_id: FxHashMap::default(),
generator_kind: None,
task_context: None,
current_item: None,
@@ -402,19 +402,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let hir_hash = self.compute_hir_hash();

let mut def_id_to_hir_id = IndexVec::default();

for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
if let Some(def_id) = self.resolver.opt_local_def_id(node_id) {
if def_id_to_hir_id.len() <= def_id.index() {
def_id_to_hir_id.resize(def_id.index() + 1, None);
}
def_id_to_hir_id[def_id] = hir_id;
}
}

self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);

let krate = hir::Crate { owners: self.owners, hir_hash };
self.arena.alloc(krate)
}
@@ -427,7 +414,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.owners
.iter_enumerated()
.filter_map(|(def_id, info)| {
let info = info.as_ref()?;
let info = info.as_owner()?;
let def_path_hash = definitions.def_path_hash(def_id);
Some((def_path_hash, info))
})
@@ -449,56 +436,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies);
let current_node_ids = std::mem::take(&mut self.local_node_ids);
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
let current_local_counter =
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));

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

let item = f(self);
debug_assert_eq!(def_id, item.def_id());
let info = self.make_owner_info(item);

self.attrs = current_attrs;
self.bodies = current_bodies;
self.local_node_ids = current_node_ids;
self.node_id_to_local_id = current_node_ids;
self.current_hir_id_owner = current_owner;
self.item_local_id_counter = current_local_counter;

let _old = self.owners.insert(def_id, info);
debug_assert!(_old.is_none());
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
self.owners[def_id] = hir::MaybeOwner::Owner(self.arena.alloc(info));

def_id
}

fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
let attrs = std::mem::take(&mut self.attrs);
let mut bodies = std::mem::take(&mut self.bodies);
let local_node_ids = std::mem::take(&mut self.local_node_ids);
let node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);

let local_id_to_def_id = local_node_ids
let local_id_to_def_id = node_id_to_local_id
.iter()
.filter_map(|&node_id| {
let hir_id = self.node_id_to_hir_id[node_id]?;
if hir_id.local_id == hir::ItemLocalId::new(0) {
None
} else {
let def_id = self.resolver.opt_local_def_id(node_id)?;
Some((hir_id.local_id, def_id))
.filter_map(|(&node_id, &local_id)| {
let def_id = self.resolver.opt_local_def_id(node_id)?;

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

if local_id == hir::ItemLocalId::new(0) { None } else { Some((local_id, def_id)) }
})
.collect();

let trait_map = local_node_ids
let trait_map = node_id_to_local_id
.into_iter()
.filter_map(|node_id| {
let hir_id = self.node_id_to_hir_id[node_id]?;
.filter_map(|(node_id, local_id)| {
let traits = self.resolver.take_trait_map(node_id)?;
Some((hir_id.local_id, traits.into_boxed_slice()))
Some((local_id, traits.into_boxed_slice()))
})
.collect();

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

*self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
// Generate a new `HirId`.
let owner = self.current_hir_id_owner;
let local_id = self.item_local_id_counter;
self.item_local_id_counter.increment_by(1);
self.local_node_ids.push(ast_node_id);
hir::HirId { owner, local_id }
})
let owner = self.current_hir_id_owner;
let local_id = match self.node_id_to_local_id.entry(ast_node_id) {
Entry::Occupied(o) => *o.get(),
Entry::Vacant(v) => {
// Generate a new `HirId`.
let local_id = self.item_local_id_counter;
self.item_local_id_counter.increment_by(1);
v.insert(local_id);
local_id
}
};
hir::HirId { owner, local_id }
}

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

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

fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
13 changes: 13 additions & 0 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
@@ -603,6 +603,19 @@ impl<Id> Res<Id> {
}
}

pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
Ok(match self {
Res::Def(kind, id) => Res::Def(kind, id),
Res::SelfCtor(id) => Res::SelfCtor(id),
Res::PrimTy(id) => Res::PrimTy(id),
Res::Local(id) => Res::Local(map(id)?),
Res::SelfTy(a, b) => Res::SelfTy(a, b),
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
})
}

#[track_caller]
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
self.map_id(|_| panic!("unexpected `Res::Local`"))
31 changes: 1 addition & 30 deletions compiler/rustc_hir/src/definitions.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
pub use crate::def_id::DefPathHash;
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::def_path_hash_map::DefPathHashMap;
use crate::hir;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
@@ -101,13 +100,6 @@ impl DefPathTable {
pub struct Definitions {
table: DefPathTable,

/// Only [`LocalDefId`]s for items and item-like are HIR owners.
/// The associated `HirId` has a `local_id` of `0`.
/// Generic parameters and closures are also assigned a `LocalDefId` but are not HIR owners.
/// Their `HirId`s are defined by their position while lowering the enclosing owner.
// FIXME(cjgillot) Some `LocalDefId`s from `use` items are dropped during lowering and lack a `HirId`.
pub(super) def_id_to_hir_id: IndexVec<LocalDefId, Option<hir::HirId>>,

/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,

@@ -322,12 +314,6 @@ impl Definitions {
})
}

#[inline]
#[track_caller]
pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId {
self.def_id_to_hir_id[id].unwrap()
}

/// Adds a root definition (no parent) and a few other reserved definitions.
pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
let key = DefKey {
@@ -354,7 +340,6 @@ impl Definitions {

Definitions {
table,
def_id_to_hir_id: Default::default(),
expansions_that_defined: Default::default(),
def_id_to_span,
stable_crate_id,
@@ -406,20 +391,6 @@ impl Definitions {
def_id
}

/// Initializes the `LocalDefId` to `HirId` mapping once it has been generated during
/// AST to HIR lowering.
pub fn init_def_id_to_hir_id_mapping(
&mut self,
mapping: IndexVec<LocalDefId, Option<hir::HirId>>,
) {
assert!(
self.def_id_to_hir_id.is_empty(),
"trying to initialize `LocalDefId` <-> `HirId` mappings twice"
);

self.def_id_to_hir_id = mapping;
}

pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId {
self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root)
}
@@ -431,7 +402,7 @@ impl Definitions {
}

pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
self.table.def_path_hashes.indices().map(|local_def_index| LocalDefId { local_def_index })
}

#[inline(always)]
48 changes: 43 additions & 5 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -711,6 +711,15 @@ pub struct OwnerNodes<'tcx> {
pub local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
}

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

/// Full information resulting from lowering an AST node.
#[derive(Debug, HashStable_Generic)]
pub struct OwnerInfo<'hir> {
@@ -728,10 +737,39 @@ pub struct OwnerInfo<'hir> {
impl<'tcx> OwnerInfo<'tcx> {
#[inline]
pub fn node(&self) -> OwnerNode<'tcx> {
use rustc_index::vec::Idx;
let node = self.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
node
self.nodes.node()
}
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum MaybeOwner<T> {
Owner(T),
NonOwner(HirId),
/// Used as a placeholder for unused LocalDefId.
Phantom,
}

impl<T> MaybeOwner<T> {
pub fn as_owner(self) -> Option<T> {
match self {
MaybeOwner::Owner(i) => Some(i),
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
}
}

pub fn map<U>(self, f: impl FnOnce(T) -> U) -> MaybeOwner<U> {
match self {
MaybeOwner::Owner(i) => MaybeOwner::Owner(f(i)),
MaybeOwner::NonOwner(hir_id) => MaybeOwner::NonOwner(hir_id),
MaybeOwner::Phantom => MaybeOwner::Phantom,
}
}

pub fn unwrap(self) -> T {
match self {
MaybeOwner::Owner(i) => i,
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => panic!("Not a HIR owner"),
}
}
}

@@ -743,7 +781,7 @@ impl<'tcx> OwnerInfo<'tcx> {
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
#[derive(Debug)]
pub struct Crate<'hir> {
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
pub owners: IndexVec<LocalDefId, MaybeOwner<&'hir OwnerInfo<'hir>>>,
pub hir_hash: Fingerprint,
}

5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/hir_id.rs
Original file line number Diff line number Diff line change
@@ -30,6 +30,11 @@ impl HirId {
if self.local_id.index() == 0 { Some(self.owner) } else { None }
}

#[inline]
pub fn is_owner(self) -> bool {
self.local_id.index() == 0
}

#[inline]
pub fn make_owner(owner: LocalDefId) -> Self {
Self { owner, local_id: ItemLocalId::from_u32(0) }
88 changes: 52 additions & 36 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
fn next(&mut self) -> Option<Self::Item> {
if self.current_id.local_id.index() != 0 {
self.current_id.local_id = ItemLocalId::new(0);
if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
if let MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) {
return Some((self.current_id.owner, node.node));
}
}
@@ -141,7 +141,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
self.current_id = HirId::make_owner(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 MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) {
return Some((self.current_id.owner, node.node));
}
}
@@ -155,14 +155,14 @@ impl<'hir> Map<'hir> {

pub fn root_module(&self) -> &'hir Mod<'hir> {
match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) {
Some(OwnerNode::Crate(item)) => item,
MaybeOwner::Owner(OwnerNode::Crate(item)) => item,
_ => bug!(),
}
}

pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
let krate = self.krate();
krate.owners.iter().filter_map(|owner| match owner.as_ref()?.node() {
krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() {
OwnerNode::Item(item) => Some(item),
_ => None,
})
@@ -205,7 +205,8 @@ impl<'hir> Map<'hir> {
Some(hir_id.owner)
} else {
self.tcx
.hir_owner_nodes(hir_id.owner)?
.hir_owner_nodes(hir_id.owner)
.as_owner()?
.local_id_to_def_id
.get(&hir_id.local_id)
.copied()
@@ -214,8 +215,12 @@ impl<'hir> Map<'hir> {

#[inline]
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
// FIXME(#85914) is this access safe for incr. comp.?
self.tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id)
let owner = self.tcx.hir_owner(def_id);
match owner {
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
MaybeOwner::NonOwner(hir_id) => hir_id,
}
}

pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
@@ -226,8 +231,7 @@ impl<'hir> Map<'hir> {
}

pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
let hir_id = self.local_def_id_to_hir_id(local_def_id);
let def_kind = match self.find(hir_id)? {
let def_kind = match self.find_by_def_id(local_def_id)? {
Node::Item(item) => match item.kind {
ItemKind::Static(..) => DefKind::Static,
ItemKind::Const(..) => DefKind::Const,
@@ -267,6 +271,7 @@ impl<'hir> Map<'hir> {
// FIXME(eddyb) is this even possible, if we have a `Node::Ctor`?
assert_ne!(variant_data.ctor_hir_id(), None);

let hir_id = self.local_def_id_to_hir_id(local_def_id);
let ctor_of = match self.find(self.get_parent_node(hir_id)) {
Some(Node::Item(..)) => def::CtorOf::Struct,
Some(Node::Variant(..)) => def::CtorOf::Variant,
@@ -275,6 +280,7 @@ impl<'hir> Map<'hir> {
DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data))
}
Node::AnonConst(_) => {
let hir_id = self.local_def_id_to_hir_id(local_def_id);
let inline = match self.find(self.get_parent_node(hir_id)) {
Some(Node::Expr(&Expr {
kind: ExprKind::ConstBlock(ref anon_const), ..
@@ -287,7 +293,10 @@ impl<'hir> Map<'hir> {
Node::Expr(expr) => match expr.kind {
ExprKind::Closure(.., None) => DefKind::Closure,
ExprKind::Closure(.., Some(_)) => DefKind::Generator,
_ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)),
_ => {
let hir_id = self.local_def_id_to_hir_id(local_def_id);
bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id))
}
},
Node::GenericParam(param) => match param.kind {
GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
@@ -321,7 +330,7 @@ impl<'hir> Map<'hir> {
if id.local_id == ItemLocalId::from_u32(0) {
Some(self.tcx.hir_owner_parent(id.owner))
} else {
let owner = self.tcx.hir_owner_nodes(id.owner)?;
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
let hir_id = HirId { owner: id.owner, local_id: node.parent };
Some(hir_id)
@@ -335,10 +344,10 @@ impl<'hir> Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(&self, id: HirId) -> Option<Node<'hir>> {
if id.local_id == ItemLocalId::from_u32(0) {
let owner = self.tcx.hir_owner(id.owner)?;
let owner = self.tcx.hir_owner(id.owner).as_owner()?;
Some(owner.node.into())
} else {
let owner = self.tcx.hir_owner_nodes(id.owner)?;
let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?;
let node = owner.nodes[id.local_id].as_ref()?;
Some(node.node)
}
@@ -347,7 +356,12 @@ impl<'hir> Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn find_by_def_id(&self, id: LocalDefId) -> Option<Node<'hir>> {
self.find(self.local_def_id_to_hir_id(id))
let owner = self.tcx.hir_owner(id);
match owner {
MaybeOwner::Owner(o) => Some(o.node.into()),
MaybeOwner::NonOwner(hir_id) => self.find(hir_id),
MaybeOwner::Phantom => bug!("No HirId for {:?}", id),
}
}

/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
@@ -362,11 +376,11 @@ impl<'hir> Map<'hir> {
}

pub fn get_if_local(&self, id: DefId) -> Option<Node<'hir>> {
id.as_local().and_then(|id| self.find(self.local_def_id_to_hir_id(id)))
id.as_local().and_then(|id| self.find_by_def_id(id))
}

pub fn get_generics(&self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
let node = self.tcx.hir_owner(id)?;
let node = self.tcx.hir_owner(id).as_owner()?;
match node.node {
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
@@ -522,7 +536,7 @@ impl<'hir> Map<'hir> {
.owners
.iter_enumerated()
.flat_map(move |(owner, owner_info)| {
let bodies = &owner_info.as_ref()?.nodes.bodies;
let bodies = &owner_info.as_owner()?.nodes.bodies;
Some(bodies.iter().map(move |&(local_id, _)| {
let hir_id = HirId { owner, local_id };
let body_id = BodyId { hir_id };
@@ -539,7 +553,7 @@ impl<'hir> Map<'hir> {

par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| {
let owner = LocalDefId::new(owner);
if let Some(owner_info) = owner_info {
if let MaybeOwner::Owner(owner_info) = owner_info {
par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| {
let hir_id = HirId { owner, local_id: *local_id };
let body_id = BodyId { hir_id };
@@ -583,10 +597,10 @@ impl<'hir> Map<'hir> {
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
let hir_id = HirId::make_owner(module);
match self.tcx.hir_owner(module).map(|o| o.node) {
Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
(m, span, hir_id)
}
Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
MaybeOwner::Owner(OwnerNode::Item(&Item {
span, kind: ItemKind::Mod(ref m), ..
})) => (m, span, hir_id),
MaybeOwner::Owner(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
node => panic!("not a module: {:?}", node),
}
}
@@ -601,7 +615,7 @@ impl<'hir> Map<'hir> {
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
let krate = self.krate();
for (owner, info) in krate.owners.iter_enumerated() {
if let Some(info) = info {
if let MaybeOwner::Owner(info) = info {
for (local_id, attrs) in info.attrs.map.iter() {
let id = HirId { owner, local_id: *local_id };
for a in *attrs {
@@ -625,7 +639,7 @@ impl<'hir> Map<'hir> {
V: itemlikevisit::ItemLikeVisitor<'hir>,
{
let krate = self.krate();
for owner in krate.owners.iter().filter_map(Option::as_ref) {
for owner in krate.owners.iter().filter_map(|i| i.as_owner()) {
match owner.node() {
OwnerNode::Item(item) => visitor.visit_item(item),
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
@@ -642,12 +656,14 @@ impl<'hir> Map<'hir> {
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
{
let krate = self.krate();
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(OwnerInfo::node) {
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
Some(OwnerNode::Crate(_)) | None => {}
par_for_each_in(&krate.owners.raw, |owner| match owner.map(OwnerInfo::node) {
MaybeOwner::Owner(OwnerNode::Item(item)) => visitor.visit_item(item),
MaybeOwner::Owner(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
MaybeOwner::Owner(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
MaybeOwner::Owner(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
MaybeOwner::Owner(OwnerNode::Crate(_))
| MaybeOwner::NonOwner(_)
| MaybeOwner::Phantom => {}
})
}

@@ -878,7 +894,7 @@ impl<'hir> Map<'hir> {

pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
let parent = self.get_parent_item(hir_id);
if let Some(node) = self.tcx.hir_owner(parent) {
if let MaybeOwner::Owner(node) = self.tcx.hir_owner(parent) {
if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node
{
return *abi;
@@ -892,21 +908,21 @@ impl<'hir> Map<'hir> {

pub fn expect_item(&self, id: LocalDefId) -> &'hir Item<'hir> {
match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::Item(item), .. }) => item,
MaybeOwner::Owner(Owner { node: OwnerNode::Item(item), .. }) => item,
_ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))),
}
}

pub fn expect_impl_item(&self, id: LocalDefId) -> &'hir ImplItem<'hir> {
match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item,
MaybeOwner::Owner(Owner { node: OwnerNode::ImplItem(item), .. }) => item,
_ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))),
}
}

pub fn expect_trait_item(&self, id: LocalDefId) -> &'hir TraitItem<'hir> {
match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item,
MaybeOwner::Owner(Owner { node: OwnerNode::TraitItem(item), .. }) => item,
_ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))),
}
}
@@ -920,7 +936,7 @@ impl<'hir> Map<'hir> {

pub fn expect_foreign_item(&self, id: LocalDefId) -> &'hir ForeignItem<'hir> {
match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item,
MaybeOwner::Owner(Owner { node: OwnerNode::ForeignItem(item), .. }) => item,
_ => {
bug!("expected foreign item, found {}", self.node_to_string(HirId::make_owner(id)))
}
@@ -1121,7 +1137,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
.owners
.iter_enumerated()
.filter_map(|(def_id, info)| {
let _ = info.as_ref()?;
let _ = info.as_owner()?;
let def_path_hash = definitions.def_path_hash(def_id);
let span = definitions.def_span(def_id);
debug_assert_eq!(span.parent(), None);
18 changes: 10 additions & 8 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -65,20 +65,20 @@ pub fn provide(providers: &mut Providers) {
providers.crate_hash = map::crate_hash;
providers.hir_module_items = map::hir_module_items;
providers.hir_owner = |tcx, id| {
let owner = tcx.hir_crate(()).owners.get(id)?.as_ref()?;
let node = owner.node();
Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies })
tcx.hir_crate(()).owners[id].map(|owner| {
let node = owner.nodes.node();
Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }
})
};
providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|i| &i.nodes);
providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].map(|i| &i.nodes);
providers.hir_owner_parent = |tcx, id| {
// Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash.
let parent = tcx.untracked_resolutions.definitions.def_key(id).parent;
let parent = parent.map_or(CRATE_HIR_ID, |local_def_index| {
let def_id = LocalDefId { local_def_index };
let mut parent_hir_id =
tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id);
let mut parent_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
if let Some(local_id) =
tcx.hir_crate(()).owners[parent_hir_id.owner].as_ref().unwrap().parenting.get(&id)
tcx.hir_crate(()).owners[parent_hir_id.owner].unwrap().parenting.get(&id)
{
parent_hir_id.local_id = *local_id;
}
@@ -87,7 +87,7 @@ pub fn provide(providers: &mut Providers) {
parent
};
providers.hir_attrs =
|tcx, id| tcx.hir_crate(()).owners[id].as_ref().map_or(AttributeMap::EMPTY, |o| &o.attrs);
|tcx, id| tcx.hir_crate(()).owners[id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs);
providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id);
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
providers.fn_arg_names = |tcx, id| {
@@ -111,4 +111,6 @@ pub fn provide(providers: &mut Providers) {
let id = id.expect_local();
tcx.resolutions(()).definitions.expansion_that_defined(id)
};
providers.in_scope_traits_map =
|tcx, id| tcx.hir_crate(()).owners[id].as_owner().map(|owner_info| &owner_info.trait_map);
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ rustc_queries! {
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_owner(key: LocalDefId) -> Option<crate::hir::Owner<'tcx>> {
query hir_owner(key: LocalDefId) -> hir::MaybeOwner<crate::hir::Owner<'tcx>> {
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
}

@@ -68,7 +68,7 @@ rustc_queries! {
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
query hir_owner_nodes(key: LocalDefId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> {
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
}

2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -2875,8 +2875,6 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
}

pub fn provide(providers: &mut ty::query::Providers) {
providers.in_scope_traits_map =
|tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map);
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
providers.module_reexports =
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
@@ -579,7 +579,7 @@ fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx
let mut hcx = tcx.create_no_span_stable_hashing_context();
let mut stable_hasher = StableHasher::new();
let owner = hir_body.id().hir_id.owner;
let bodies = &tcx.hir_owner_nodes(owner).as_ref().unwrap().bodies;
let bodies = &tcx.hir_owner_nodes(owner).unwrap().bodies;
hcx.with_hir_bodies(false, owner, bodies, |hcx| {
hir_body.value.hash_stable(hcx, &mut stable_hasher)
});
10 changes: 1 addition & 9 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -1019,15 +1019,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir().get_parent_node(hir_id);
// FIXME(cjgillot) Can this check be replaced by
// `let parent_is_item = parent_id.is_owner();`?
let parent_is_item = if let Some(parent_def_id) = parent_id.as_owner() {
matches!(self.tcx.hir().krate().owners.get(parent_def_id), Some(Some(_)),)
} else {
false
};

if !parent_is_item {
if !parent_id.is_owner() {
if !self.trait_definition_only {
struct_span_err!(
self.tcx.sess,