1
Fork 0

Auto merge of #93438 - spastorino:node_id_to_hir_id_refactor, r=oli-obk

Node id to hir id refactor

Related to #89278

r? `@oli-obk`
This commit is contained in:
bors 2022-02-24 01:26:57 +00:00
commit 8ebec97e09
3 changed files with 74 additions and 59 deletions

View file

@ -360,7 +360,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// method, it will not be considered an in-band // method, it will not be considered an in-band
// lifetime to be added, but rather a reference to a // lifetime to be added, but rather a reference to a
// parent lifetime. // parent lifetime.
let lowered_trait_def_id = self.lower_node_id(id).expect_owner(); let lowered_trait_def_id = hir_id.expect_owner();
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs( let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
ast_generics, ast_generics,
lowered_trait_def_id, lowered_trait_def_id,
@ -509,10 +509,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
let new_id = self.resolver.local_def_id(new_node_id); let new_id = self.resolver.local_def_id(new_node_id);
let Some(res) = resolutions.next() else { let Some(res) = resolutions.next() else {
// Associate an HirId to both ids even if there is no resolution. // 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); self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
let _old = std::mem::replace( let _old = std::mem::replace(
&mut self.owners[new_id], &mut self.owners[new_id],

View file

@ -44,7 +44,7 @@ use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint; 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::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -54,7 +54,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::intravisit; use rustc_hir::intravisit;
use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_session::lint::LintBuffer; use rustc_session::lint::LintBuffer;
@ -67,6 +67,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::hash_map::Entry;
use tracing::{debug, trace}; use tracing::{debug, trace};
macro_rules! arena_vec { macro_rules! arena_vec {
@ -154,10 +155,11 @@ struct LoweringContext<'a, 'hir: 'a> {
current_hir_id_owner: LocalDefId, current_hir_id_owner: LocalDefId,
item_local_id_counter: hir::ItemLocalId, item_local_id_counter: hir::ItemLocalId,
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>, local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
/// NodeIds that are lowered inside the current HIR owner. /// 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_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>, allow_gen_future: Option<Lrc<[Symbol]>>,
@ -368,8 +370,9 @@ pub fn lower_crate<'a, 'hir>(
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
current_hir_id_owner: CRATE_DEF_ID, current_hir_id_owner: CRATE_DEF_ID,
item_local_id_counter: hir::ItemLocalId::new(0), item_local_id_counter: hir::ItemLocalId::new(0),
node_id_to_hir_id: IndexVec::new(), node_id_to_local_id: FxHashMap::default(),
local_node_ids: Vec::new(), local_id_to_def_id: SortedMap::new(),
trait_map: FxHashMap::default(),
generator_kind: None, generator_kind: None,
task_context: None, task_context: None,
current_item: None, current_item: None,
@ -496,15 +499,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let current_attrs = std::mem::take(&mut self.attrs); let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies); 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_id_to_def_id = std::mem::take(&mut self.local_id_to_def_id);
let current_trait_map = std::mem::take(&mut self.trait_map);
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id); let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
let current_local_counter = let current_local_counter =
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
// Always allocate the first `HirId` for the owner itself. // 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); debug_assert_eq!(_old, None);
self.local_node_ids.push(owner);
let item = f(self); let item = f(self);
debug_assert_eq!(def_id, item.def_id()); debug_assert_eq!(def_id, item.def_id());
@ -512,7 +516,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.attrs = current_attrs; self.attrs = current_attrs;
self.bodies = current_bodies; self.bodies = current_bodies;
self.local_node_ids = current_node_ids; self.node_id_to_local_id = current_node_ids;
self.local_id_to_def_id = current_id_to_def_id;
self.trait_map = current_trait_map;
self.current_hir_id_owner = current_owner; self.current_hir_id_owner = current_owner;
self.item_local_id_counter = current_local_counter; self.item_local_id_counter = current_local_counter;
@ -525,34 +531,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> { fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
let attrs = std::mem::take(&mut self.attrs); let attrs = std::mem::take(&mut self.attrs);
let mut bodies = std::mem::take(&mut self.bodies); let mut bodies = std::mem::take(&mut self.bodies);
let local_node_ids = std::mem::take(&mut self.local_node_ids);
let local_id_to_def_id = local_node_ids
.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)?;
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.
*o = hir::MaybeOwner::NonOwner(hir_id);
}
Some((hir_id.local_id, def_id))
}
})
.collect();
let trait_map = local_node_ids
.into_iter()
.filter_map(|node_id| {
let hir_id = self.node_id_to_hir_id[node_id]?;
let traits = self.resolver.take_trait_map(node_id)?;
Some((hir_id.local_id, traits.into_boxed_slice()))
})
.collect();
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
for (id, attrs) in attrs.iter() { for (id, attrs) in attrs.iter() {
@ -572,7 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hash_without_bodies, hash_without_bodies,
nodes, nodes,
bodies, bodies,
local_id_to_def_id, local_id_to_def_id: std::mem::take(&mut self.local_id_to_def_id),
}; };
let attrs = { let attrs = {
let mut hcx = self.resolver.create_stable_hashing_context(); let mut hcx = self.resolver.create_stable_hashing_context();
@ -582,7 +560,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::AttributeMap { map: attrs, hash } hir::AttributeMap { map: attrs, hash }
}; };
hir::OwnerInfo { nodes, parenting, attrs, trait_map } hir::OwnerInfo { nodes, parenting, attrs, trait_map: std::mem::take(&mut self.trait_map) }
} }
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate /// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
@ -615,14 +593,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId { fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
assert_ne!(ast_node_id, DUMMY_NODE_ID); assert_ne!(ast_node_id, DUMMY_NODE_ID);
*self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || { match self.node_id_to_local_id.entry(ast_node_id) {
Entry::Occupied(o) => {
hir::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
}
Entry::Vacant(v) => {
// Generate a new `HirId`. // Generate a new `HirId`.
let owner = self.current_hir_id_owner; let owner = self.current_hir_id_owner;
let local_id = self.item_local_id_counter; let local_id = self.item_local_id_counter;
let hir_id = hir::HirId { owner, local_id };
v.insert(local_id);
self.item_local_id_counter.increment_by(1); self.item_local_id_counter.increment_by(1);
self.local_node_ids.push(ast_node_id);
hir::HirId { owner, local_id } assert_ne!(local_id, hir::ItemLocalId::new(0));
}) if let Some(def_id) = self.resolver.opt_local_def_id(ast_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.
*o = hir::MaybeOwner::NonOwner(hir_id);
}
self.local_id_to_def_id.insert(local_id, def_id);
}
if let Some(traits) = self.resolver.take_trait_map(ast_node_id) {
self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
}
hir_id
}
}
} }
fn next_id(&mut self) -> hir::HirId { fn next_id(&mut self) -> hir::HirId {
@ -631,11 +631,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
fn lower_res(&mut self, res: Res<NodeId>) -> Res { fn lower_res(&mut self, res: Res<NodeId>) -> Res {
res.map_id(|id| { let res: Result<Res, ()> = res.apply_id(|id| {
self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| { let owner = self.current_hir_id_owner;
panic!("expected `NodeId` to be lowered already for res {:#?}", res); 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> { fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
@ -1476,7 +1482,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetime_defs = let lifetime_defs =
lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(|&(name, span)| { lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(|&(name, span)| {
let def_node_id = lctx.resolver.next_node_id(); let def_node_id = lctx.resolver.next_node_id();
let hir_id = lctx.lower_node_id(def_node_id);
lctx.resolver.create_def( lctx.resolver.create_def(
opaque_ty_def_id, opaque_ty_def_id,
def_node_id, def_node_id,
@ -1484,6 +1489,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExpnId::root(), ExpnId::root(),
span.with_parent(None), span.with_parent(None),
); );
let hir_id = lctx.lower_node_id(def_node_id);
let (name, kind) = match name { let (name, kind) = match name {
hir::LifetimeName::Underscore => ( hir::LifetimeName::Underscore => (

View file

@ -611,6 +611,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 { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
})
}
#[track_caller] #[track_caller]
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> { pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
self.map_id(|_| panic!("unexpected `Res::Local`")) self.map_id(|_| panic!("unexpected `Res::Local`"))