Skip to content

Commit

Permalink
Auto merge of #79318 - cjgillot:fitem, r=lcnr
Browse files Browse the repository at this point in the history
Store HIR ForeignItem in a side table

In a similar fashion to Item, ImplItem and TraitItem.
  • Loading branch information
bors committed Nov 27, 2020
2 parents 361543d + d6b22fa commit c922857
Show file tree
Hide file tree
Showing 56 changed files with 400 additions and 226 deletions.
30 changes: 25 additions & 5 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
items: BTreeSet::new(),
trait_items: BTreeSet::new(),
impl_items: BTreeSet::new(),
foreign_items: BTreeSet::new(),
},
);

Expand Down Expand Up @@ -105,6 +106,18 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {

visit::walk_assoc_item(self, item, ctxt);
}

fn visit_foreign_item(&mut self, item: &'a ForeignItem) {
self.lctx.allocate_hir_id_counter(item.id);
self.lctx.with_hir_id_owner(item.id, |lctx| {
let hir_item = lctx.lower_foreign_item(item);
let id = hir::ForeignItemId { hir_id: hir_item.hir_id };
lctx.foreign_items.insert(id, hir_item);
lctx.modules.get_mut(&lctx.current_module).unwrap().foreign_items.insert(id);
});

visit::walk_foreign_item(self, item);
}
}

impl<'hir> LoweringContext<'_, 'hir> {
Expand Down Expand Up @@ -304,7 +317,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
})
}
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
},
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
// We lower
Expand Down Expand Up @@ -704,10 +722,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod<'hir> {
hir::ForeignMod {
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
items: self.arena.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item(x))),
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
hir::ForeignItemRef {
id: hir::ForeignItemId { hir_id: self.lower_node_id(i.id) },
ident: i.ident,
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
}
}

Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct LoweringContext<'a, 'hir: 'a> {

trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
foreign_items: BTreeMap<hir::ForeignItemId, hir::ForeignItem<'hir>>,
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
exported_macros: Vec<hir::MacroDef<'hir>>,
non_exported_macro_attrs: Vec<ast::Attribute>,
Expand Down Expand Up @@ -298,6 +299,7 @@ pub fn lower_crate<'a, 'hir>(
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
foreign_items: BTreeMap::new(),
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
modules: BTreeMap::new(),
Expand Down Expand Up @@ -485,6 +487,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
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);
}

fn visit_ty(&mut self, t: &'tcx Ty) {
match t.kind {
// Mirrors the case in visit::walk_ty
Expand Down Expand Up @@ -548,6 +555,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
items: self.items,
trait_items: self.trait_items,
impl_items: self.impl_items,
foreign_items: self.foreign_items,
bodies: self.bodies,
body_ids,
trait_impls: self.trait_impls,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ macro_rules! arena_types {
[] field_pat: rustc_hir::FieldPat<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[few] foreign_item_ref: rustc_hir::ForeignItemRef<$tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
Expand Down
52 changes: 42 additions & 10 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ pub struct ModuleItems {
pub items: BTreeSet<HirId>,
pub trait_items: BTreeSet<TraitItemId>,
pub impl_items: BTreeSet<ImplItemId>,
pub foreign_items: BTreeSet<ForeignItemId>,
}

/// A type representing only the top-level module.
Expand Down Expand Up @@ -612,6 +613,7 @@ pub struct Crate<'hir> {

pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
pub foreign_items: BTreeMap<ForeignItemId, ForeignItem<'hir>>,
pub bodies: BTreeMap<BodyId, Body<'hir>>,
pub trait_impls: BTreeMap<DefId, Vec<HirId>>,

Expand Down Expand Up @@ -644,6 +646,10 @@ impl Crate<'hir> {
&self.impl_items[&id]
}

pub fn foreign_item(&self, id: ForeignItemId) -> &ForeignItem<'hir> {
&self.foreign_items[&id]
}

pub fn body(&self, id: BodyId) -> &Body<'hir> {
&self.bodies[&id]
}
Expand Down Expand Up @@ -673,6 +679,10 @@ impl Crate<'_> {
for impl_item in self.impl_items.values() {
visitor.visit_impl_item(impl_item);
}

for foreign_item in self.foreign_items.values() {
visitor.visit_foreign_item(foreign_item);
}
}

/// A parallel version of `visit_all_item_likes`.
Expand All @@ -695,6 +705,11 @@ impl Crate<'_> {
par_for_each_in(&self.impl_items, |(_, impl_item)| {
visitor.visit_impl_item(impl_item);
});
},
{
par_for_each_in(&self.foreign_items, |(_, foreign_item)| {
visitor.visit_foreign_item(foreign_item);
});
}
);
}
Expand Down Expand Up @@ -1840,7 +1855,7 @@ pub struct FnSig<'hir> {
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct TraitItemId {
Expand Down Expand Up @@ -1884,7 +1899,7 @@ pub enum TraitItemKind<'hir> {
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ImplItemId {
Expand Down Expand Up @@ -2269,12 +2284,6 @@ pub struct Mod<'hir> {
pub item_ids: &'hir [ItemId],
}

#[derive(Debug, HashStable_Generic)]
pub struct ForeignMod<'hir> {
pub abi: Abi,
pub items: &'hir [ForeignItem<'hir>],
}

#[derive(Encodable, Debug, HashStable_Generic)]
pub struct GlobalAsm {
pub asm: Symbol,
Expand Down Expand Up @@ -2432,7 +2441,7 @@ impl VariantData<'hir> {
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the node-id of the item
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, Encodable, Debug)]
pub struct ItemId {
Expand Down Expand Up @@ -2521,7 +2530,7 @@ pub enum ItemKind<'hir> {
/// A module.
Mod(Mod<'hir>),
/// An external module, e.g. `extern { .. }`.
ForeignMod(ForeignMod<'hir>),
ForeignMod { abi: Abi, items: &'hir [ForeignItemRef<'hir>] },
/// Module-level inline assembly (from `global_asm!`).
GlobalAsm(&'hir GlobalAsm),
/// A type alias, e.g., `type Foo = Bar<u8>`.
Expand Down Expand Up @@ -2614,6 +2623,29 @@ pub enum AssocItemKind {
Type,
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
pub struct ForeignItemId {
pub hir_id: HirId,
}

/// A reference from a foreign block to one of its items. This
/// contains the item's ID, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, HashStable_Generic)]
pub struct ForeignItemRef<'hir> {
pub id: ForeignItemId,
#[stable_hasher(project(name))]
pub ident: Ident,
pub span: Span,
pub vis: Visibility<'hir>,
}

#[derive(Debug, HashStable_Generic)]
pub struct ForeignItem<'hir> {
#[stable_hasher(project(name))]
Expand Down
38 changes: 36 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ where
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>) {
self.visitor.visit_impl_item(impl_item);
}

fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
self.visitor.visit_foreign_item(foreign_item);
}
}

pub trait IntoVisitor<'hir> {
Expand All @@ -88,6 +92,10 @@ where
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>) {
self.0.into_visitor().visit_impl_item(impl_item);
}

fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>) {
self.0.into_visitor().visit_foreign_item(foreign_item);
}
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -128,6 +136,7 @@ pub trait Map<'hir> {
fn item(&self, id: HirId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
}

/// An erased version of `Map<'hir>`, using dynamic dispatch.
Expand All @@ -150,6 +159,9 @@ impl<'hir> Map<'hir> for ErasedMap<'hir> {
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
self.0.impl_item(id)
}
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
self.0.foreign_item(id)
}
}

/// Specifies what nested things a visitor wants to visit. The most
Expand Down Expand Up @@ -277,6 +289,14 @@ pub trait Visitor<'v>: Sized {
walk_list!(self, visit_impl_item, opt_item);
}

/// Like `visit_nested_item()`, but for foreign items. See
/// `visit_nested_item()` for advice on when to override this
/// method.
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) {
let opt_item = self.nested_visit_map().inter().map(|map| map.foreign_item(id));
walk_list!(self, visit_foreign_item, opt_item);
}

/// Invoked to visit the body of a function, method or closure. Like
/// visit_nested_item, does nothing by default unless you override
/// `nested_visit_map` to return other than `None`, in which case it will walk
Expand Down Expand Up @@ -378,6 +398,9 @@ pub trait Visitor<'v>: Sized {
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) {
walk_impl_item(self, ii)
}
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef<'v>) {
walk_foreign_item_ref(self, ii)
}
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef<'v>) {
walk_impl_item_ref(self, ii)
}
Expand Down Expand Up @@ -566,9 +589,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
visitor.visit_mod(module, item.span, item.hir_id)
}
ItemKind::ForeignMod(ref foreign_module) => {
ItemKind::ForeignMod { abi: _, items } => {
visitor.visit_id(item.hir_id);
walk_list!(visitor, visit_foreign_item, foreign_module.items);
walk_list!(visitor, visit_foreign_item_ref, items);
}
ItemKind::GlobalAsm(_) => {
visitor.visit_id(item.hir_id);
Expand Down Expand Up @@ -1012,6 +1035,17 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
}
}

pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V,
foreign_item_ref: &'v ForeignItemRef<'v>,
) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ForeignItemRef { id, ident, span: _, ref vis } = *foreign_item_ref;
visitor.visit_nested_foreign_item(id);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
}

pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/itemlikevisit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{ImplItem, Item, TraitItem};
use super::{ForeignItem, ImplItem, Item, TraitItem};

/// The "item-like visitor" defines only the top-level methods
/// that can be invoked by `Crate::visit_all_item_likes()`. Whether
Expand Down Expand Up @@ -47,11 +47,13 @@ pub trait ItemLikeVisitor<'hir> {
fn visit_item(&mut self, item: &'hir Item<'hir>);
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem<'hir>);
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>);
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>);
}

/// A parallel variant of `ItemLikeVisitor`.
pub trait ParItemLikeVisitor<'hir> {
fn visit_item(&self, item: &'hir Item<'hir>);
fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>);
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>);
fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>);
}
19 changes: 17 additions & 2 deletions compiler/rustc_hir/src/stable_hash_impls.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};

use crate::hir::{
BodyId, Expr, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId, Ty,
VisibilityKind,
BodyId, Expr, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId,
Ty, VisibilityKind,
};
use crate::hir_id::{HirId, ItemLocalId};
use rustc_span::def_id::{DefPathHash, LocalDefId};
Expand Down Expand Up @@ -52,6 +52,15 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
}
}

impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
type KeyType = (DefPathHash, ItemLocalId);

#[inline]
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
self.hir_id.to_stable_hash_key(hcx)
}
}

impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HirId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_hir_id(*self, hasher)
Expand All @@ -77,6 +86,12 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ItemId {
}
}

impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItemId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_reference_to_item(self.hir_id, hasher)
}
}

impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
hcx.hash_reference_to_item(self.hir_id, hasher)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl Target {
ItemKind::Const(..) => Target::Const,
ItemKind::Fn(..) => Target::Fn,
ItemKind::Mod(..) => Target::Mod,
ItemKind::ForeignMod(..) => Target::ForeignMod,
ItemKind::ForeignMod { .. } => Target::ForeignMod,
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
ItemKind::TyAlias(..) => Target::TyAlias,
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
Expand Down
Loading

0 comments on commit c922857

Please sign in to comment.