Skip to content

Do not preallocate HirIds #88627

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

Merged
merged 2 commits into from
Sep 19, 2021
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
StmtKind::Item(ref it) => {
stmts.extend(self.lower_item_id(it).into_iter().enumerate().map(
stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map(
|(i, item_id)| {
let hir_id = match i {
0 => self.lower_node_id(s.id),
Expand Down
58 changes: 25 additions & 33 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl ItemLowerer<'_, '_, '_> {

impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
fn visit_item(&mut self, item: &'a Item) {
self.lctx.allocate_hir_id_counter(item.id);
let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| {
lctx.without_in_scope_lifetime_defs(|lctx| {
let hir_item = lctx.lower_item(item);
Expand Down Expand Up @@ -77,6 +78,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
}

fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
self.lctx.allocate_hir_id_counter(item.id);
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
AssocCtxt::Trait => {
let hir_item = lctx.lower_trait_item(item);
Expand Down Expand Up @@ -154,41 +156,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
hir::Mod {
inner: self.lower_span(inner),
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_id(x))),
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
}
}

pub(super) fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let node_ids = match i.kind {
ItemKind::Use(ref use_tree) => {
let mut vec = smallvec![i.id];
self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
vec
}
ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => {
smallvec![i.id]
}
_ => smallvec![i.id],
};

pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let mut node_ids = smallvec![hir::ItemId { def_id: self.resolver.local_def_id(i.id) }];
if let ItemKind::Use(ref use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
}
node_ids
.into_iter()
.map(|node_id| hir::ItemId {
def_id: self.allocate_hir_id_counter(node_id).expect_owner(),
})
.collect()
}

fn lower_item_id_use_tree(
&mut self,
tree: &UseTree,
base_id: NodeId,
vec: &mut SmallVec<[NodeId; 1]>,
vec: &mut SmallVec<[hir::ItemId; 1]>,
) {
match tree.kind {
UseTreeKind::Nested(ref nested_vec) => {
for &(ref nested, id) in nested_vec {
vec.push(id);
vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
self.lower_item_id_use_tree(nested, id, vec);
}
}
Expand All @@ -197,7 +186,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
for (_, &id) in
iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
{
vec.push(id);
vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
}
}
}
Expand Down Expand Up @@ -486,7 +475,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

let mut resolutions = self.expect_full_res_from_use(id);
let mut resolutions = self.expect_full_res_from_use(id).fuse();
// We want to return *something* from this function, so hold onto the first item
// for later.
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
Expand All @@ -496,7 +485,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
// won't be dealing with macros in the rest of the compiler.
// Essentially a single `use` which imports two names is desugared into
// two imports.
for (res, &new_node_id) in iter::zip(resolutions, &[id1, id2]) {
for new_node_id in [id1, id2] {
// Associate an HirId to both ids even if there is no resolution.
let new_id = self.allocate_hir_id_counter(new_node_id);

let res = if let Some(res) = resolutions.next() { res } else { continue };
let ident = *ident;
let mut path = path.clone();
for seg in &mut path.segments {
Expand All @@ -505,17 +498,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
let span = path.span;

self.with_hir_id_owner(new_node_id, |this| {
let new_id = this.lower_node_id(new_node_id);
let res = this.lower_res(res);
let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
let vis = this.rebuild_vis(&vis);
if let Some(attrs) = attrs {
this.attrs.insert(new_id, attrs);
this.attrs.insert(hir::HirId::make_owner(new_id), attrs);
}

this.insert_item(hir::Item {
def_id: new_id.expect_owner(),
def_id: new_id,
ident: this.lower_ident(ident),
kind,
vis,
Expand Down Expand Up @@ -564,7 +556,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// Add all the nested `PathListItem`s to the HIR.
for &(ref use_tree, id) in trees {
let new_hir_id = self.lower_node_id(id);
let new_hir_id = self.allocate_hir_id_counter(id);

let mut prefix = prefix.clone();

Expand All @@ -585,11 +577,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
if let Some(attrs) = attrs {
this.attrs.insert(new_hir_id, attrs);
this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs);
}

this.insert_item(hir::Item {
def_id: new_hir_id.expect_owner(),
def_id: new_hir_id,
ident: this.lower_ident(ident),
kind,
vis,
Expand Down Expand Up @@ -700,7 +692,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
hir::ForeignItemRef {
id: hir::ForeignItemId { def_id: self.lower_node_id(i.id).expect_owner() },
id: hir::ForeignItemId { def_id: self.allocate_hir_id_counter(i.id) },
ident: self.lower_ident(i.ident),
span: self.lower_span(i.span),
vis: self.lower_visibility(&i.vis, Some(i.id)),
Expand Down Expand Up @@ -842,7 +834,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
AssocItemKind::MacCall(..) => unimplemented!(),
};
let id = hir::TraitItemId { def_id: self.lower_node_id(i.id).expect_owner() };
let id = hir::TraitItemId { def_id: self.resolver.local_def_id(i.id) };
let defaultness = hir::Defaultness::Default { has_value: has_default };
hir::TraitItemRef {
id,
Expand Down Expand Up @@ -928,7 +920,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
hir::ImplItemRef {
id: hir::ImplItemId { def_id: self.lower_node_id(i.id).expect_owner() },
id: hir::ImplItemId { def_id: self.allocate_hir_id_counter(i.id) },
ident: self.lower_ident(i.ident),
span: self.lower_span(i.span),
vis: self.lower_visibility(&i.vis, Some(i.id)),
Expand Down
65 changes: 5 additions & 60 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
use rustc_ast::node_id::NodeMap;
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::visit;
use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_data_structures::captures::Captures;
Expand Down Expand Up @@ -418,60 +418,9 @@ enum AnonymousLifetimeMode {

impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
/// Full-crate AST visitor that inserts into a fresh
/// `LoweringContext` any information that may be
/// needed from arbitrary locations in the crate,
/// e.g., the number of lifetime generic parameters
/// declared for every type and trait definition.
struct MiscCollector<'tcx, 'lowering, 'hir> {
lctx: &'tcx mut LoweringContext<'lowering, 'hir>,
}

impl MiscCollector<'_, '_, '_> {
fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree) {
match tree.kind {
UseTreeKind::Simple(_, id1, id2) => {
for id in [id1, id2] {
self.lctx.allocate_hir_id_counter(id);
}
}
UseTreeKind::Glob => (),
UseTreeKind::Nested(ref trees) => {
for &(ref use_tree, id) in trees {
self.lctx.allocate_hir_id_counter(id);
self.allocate_use_tree_hir_id_counters(use_tree);
}
}
}
}
}

impl<'tcx> Visitor<'tcx> for MiscCollector<'tcx, '_, '_> {
fn visit_item(&mut self, item: &'tcx Item) {
self.lctx.allocate_hir_id_counter(item.id);

if let ItemKind::Use(ref use_tree) = item.kind {
self.allocate_use_tree_hir_id_counters(use_tree);
}

visit::walk_item(self, item);
}

fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) {
self.lctx.allocate_hir_id_counter(item.id);
visit::walk_assoc_item(self, item, ctxt);
}

fn visit_foreign_item(&mut self, item: &'tcx ForeignItem) {
self.lctx.allocate_hir_id_counter(item.id);
visit::walk_foreign_item(self, item);
}
}

self.lower_node_id(CRATE_NODE_ID);
debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));

visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);

let module = self.arena.alloc(self.lower_mod(&c.items, c.span));
Expand Down Expand Up @@ -554,13 +503,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
id
}

fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LocalDefId {
// Set up the counter if needed.
self.item_local_id_counters.entry(owner).or_insert(0);
// Always allocate the first `HirId` for the owner itself.
let lowered = self.lower_node_id_with_owner(owner, owner);
debug_assert_eq!(lowered.local_id.as_u32(), 0);
lowered
lowered.owner
}

fn create_stable_hashing_context(&self) -> LoweringHasher<'_> {
Expand Down Expand Up @@ -1503,9 +1452,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);

let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);

self.allocate_hir_id_counter(opaque_ty_node_id);
let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id);

let collected_lifetimes = self.with_hir_id_owner(opaque_ty_node_id, move |lctx| {
let hir_bounds = lower_bounds(lctx);
Expand Down Expand Up @@ -1762,9 +1709,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);

let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);

self.allocate_hir_id_counter(opaque_ty_node_id);
let opaque_ty_def_id = self.allocate_hir_id_counter(opaque_ty_node_id);

// When we create the opaque type for this async fn, it is going to have
// to capture all the lifetimes involved in the signature (including in the
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
Expand Down Expand Up @@ -206,11 +206,6 @@ impl<'hir> Map<'hir> {
}

pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
// FIXME(eddyb) support `find` on the crate root.
if local_def_id.to_def_id().index == CRATE_DEF_INDEX {
return Some(DefKind::Mod);
}

let hir_id = self.local_def_id_to_hir_id(local_def_id);
let def_kind = match self.find(hir_id)? {
Node::Item(item) => match item.kind {
Expand Down