Skip to content

Commit 419a918

Browse files
committed
Store ForeignItem in a side table.
1 parent 65ecc48 commit 419a918

File tree

46 files changed

+270
-55
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+270
-55
lines changed

compiler/rustc_ast_lowering/src/item.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
4343
items: BTreeSet::new(),
4444
trait_items: BTreeSet::new(),
4545
impl_items: BTreeSet::new(),
46+
foreign_items: BTreeSet::new(),
4647
},
4748
);
4849

@@ -105,6 +106,17 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
105106

106107
visit::walk_assoc_item(self, item, ctxt);
107108
}
109+
110+
fn visit_foreign_item(&mut self, item: &'a ForeignItem) {
111+
self.lctx.with_hir_id_owner(item.id, |lctx| {
112+
let hir_item = lctx.lower_foreign_item(item);
113+
let id = hir::ForeignItemId { hir_id: hir_item.hir_id };
114+
lctx.foreign_items.insert(id, hir_item);
115+
lctx.modules.get_mut(&lctx.current_module).unwrap().foreign_items.insert(id);
116+
});
117+
118+
visit::walk_foreign_item(self, item);
119+
}
108120
}
109121

110122
impl<'hir> LoweringContext<'_, 'hir> {
@@ -704,10 +716,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
704716
}
705717
}
706718

719+
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef<'hir> {
720+
hir::ForeignItemRef {
721+
id: hir::ForeignItemId { hir_id: self.lower_node_id(i.id) },
722+
ident: i.ident,
723+
span: i.span,
724+
vis: self.lower_visibility(&i.vis, Some(i.id)),
725+
}
726+
}
727+
707728
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod<'hir> {
708729
hir::ForeignMod {
709730
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
710-
items: self.arena.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item(x))),
731+
items: self
732+
.arena
733+
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
711734
}
712735
}
713736

compiler/rustc_ast_lowering/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ struct LoweringContext<'a, 'hir: 'a> {
101101

102102
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
103103
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
104+
foreign_items: BTreeMap<hir::ForeignItemId, hir::ForeignItem<'hir>>,
104105
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
105106
exported_macros: Vec<hir::MacroDef<'hir>>,
106107
non_exported_macro_attrs: Vec<ast::Attribute>,
@@ -298,6 +299,7 @@ pub fn lower_crate<'a, 'hir>(
298299
items: BTreeMap::new(),
299300
trait_items: BTreeMap::new(),
300301
impl_items: BTreeMap::new(),
302+
foreign_items: BTreeMap::new(),
301303
bodies: BTreeMap::new(),
302304
trait_impls: BTreeMap::new(),
303305
modules: BTreeMap::new(),
@@ -548,6 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
548550
items: self.items,
549551
trait_items: self.trait_items,
550552
impl_items: self.impl_items,
553+
foreign_items: self.foreign_items,
551554
bodies: self.bodies,
552555
body_ids,
553556
trait_impls: self.trait_impls,

compiler/rustc_hir/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ macro_rules! arena_types {
2929
[] field_pat: rustc_hir::FieldPat<$tcx>,
3030
[] fn_decl: rustc_hir::FnDecl<$tcx>,
3131
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
32+
[] foreign_item_ref: rustc_hir::ForeignItemRef<$tcx>,
3233
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
3334
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
3435
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,

compiler/rustc_hir/src/hir.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ pub struct ModuleItems {
579579
pub items: BTreeSet<HirId>,
580580
pub trait_items: BTreeSet<TraitItemId>,
581581
pub impl_items: BTreeSet<ImplItemId>,
582+
pub foreign_items: BTreeSet<ForeignItemId>,
582583
}
583584

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

613614
pub trait_items: BTreeMap<TraitItemId, TraitItem<'hir>>,
614615
pub impl_items: BTreeMap<ImplItemId, ImplItem<'hir>>,
616+
pub foreign_items: BTreeMap<ForeignItemId, ForeignItem<'hir>>,
615617
pub bodies: BTreeMap<BodyId, Body<'hir>>,
616618
pub trait_impls: BTreeMap<DefId, Vec<HirId>>,
617619

@@ -644,6 +646,10 @@ impl Crate<'hir> {
644646
&self.impl_items[&id]
645647
}
646648

649+
pub fn foreign_item(&self, id: ForeignItemId) -> &ForeignItem<'hir> {
650+
&self.foreign_items[&id]
651+
}
652+
647653
pub fn body(&self, id: BodyId) -> &Body<'hir> {
648654
&self.bodies[&id]
649655
}
@@ -673,6 +679,10 @@ impl Crate<'_> {
673679
for impl_item in self.impl_items.values() {
674680
visitor.visit_impl_item(impl_item);
675681
}
682+
683+
for foreign_item in self.foreign_items.values() {
684+
visitor.visit_foreign_item(foreign_item);
685+
}
676686
}
677687

678688
/// A parallel version of `visit_all_item_likes`.
@@ -695,6 +705,11 @@ impl Crate<'_> {
695705
par_for_each_in(&self.impl_items, |(_, impl_item)| {
696706
visitor.visit_impl_item(impl_item);
697707
});
708+
},
709+
{
710+
par_for_each_in(&self.foreign_items, |(_, foreign_item)| {
711+
visitor.visit_foreign_item(foreign_item);
712+
});
698713
}
699714
);
700715
}
@@ -2272,7 +2287,7 @@ pub struct Mod<'hir> {
22722287
#[derive(Debug, HashStable_Generic)]
22732288
pub struct ForeignMod<'hir> {
22742289
pub abi: Abi,
2275-
pub items: &'hir [ForeignItem<'hir>],
2290+
pub items: &'hir [ForeignItemRef<'hir>],
22762291
}
22772292

22782293
#[derive(Encodable, Debug, HashStable_Generic)]
@@ -2614,6 +2629,29 @@ pub enum AssocItemKind {
26142629
Type,
26152630
}
26162631

2632+
// The bodies for items are stored "out of line", in a separate
2633+
// hashmap in the `Crate`. Here we just record the node-id of the item
2634+
// so it can fetched later.
2635+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
2636+
pub struct ForeignItemId {
2637+
pub hir_id: HirId,
2638+
}
2639+
2640+
/// A reference from a foreign block to one of its items. This
2641+
/// contains the item's ID, naturally, but also the item's name and
2642+
/// some other high-level details (like whether it is an associated
2643+
/// type or method, and whether it is public). This allows other
2644+
/// passes to find the impl they want without loading the ID (which
2645+
/// means fewer edges in the incremental compilation graph).
2646+
#[derive(Debug, HashStable_Generic)]
2647+
pub struct ForeignItemRef<'hir> {
2648+
pub id: ForeignItemId,
2649+
#[stable_hasher(project(name))]
2650+
pub ident: Ident,
2651+
pub span: Span,
2652+
pub vis: Visibility<'hir>,
2653+
}
2654+
26172655
#[derive(Debug, HashStable_Generic)]
26182656
pub struct ForeignItem<'hir> {
26192657
#[stable_hasher(project(name))]

compiler/rustc_hir/src/intravisit.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ where
6464
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem<'hir>) {
6565
self.visitor.visit_impl_item(impl_item);
6666
}
67+
68+
fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem<'hir>) {
69+
self.visitor.visit_foreign_item(foreign_item);
70+
}
6771
}
6872

6973
pub trait IntoVisitor<'hir> {
@@ -88,6 +92,10 @@ where
8892
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>) {
8993
self.0.into_visitor().visit_impl_item(impl_item);
9094
}
95+
96+
fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>) {
97+
self.0.into_visitor().visit_foreign_item(foreign_item);
98+
}
9199
}
92100

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

133142
/// An erased version of `Map<'hir>`, using dynamic dispatch.
@@ -150,6 +159,9 @@ impl<'hir> Map<'hir> for ErasedMap<'hir> {
150159
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
151160
self.0.impl_item(id)
152161
}
162+
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
163+
self.0.foreign_item(id)
164+
}
153165
}
154166

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

292+
/// Like `visit_nested_item()`, but for impl items. See
293+
/// `visit_nested_item()` for advice on when to override this
294+
/// method.
295+
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) {
296+
let opt_item = self.nested_visit_map().inter().map(|map| map.foreign_item(id));
297+
walk_list!(self, visit_foreign_item, opt_item);
298+
}
299+
280300
/// Invoked to visit the body of a function, method or closure. Like
281301
/// visit_nested_item, does nothing by default unless you override
282302
/// `nested_visit_map` to return other than `None`, in which case it will walk
@@ -378,6 +398,9 @@ pub trait Visitor<'v>: Sized {
378398
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) {
379399
walk_impl_item(self, ii)
380400
}
401+
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef<'v>) {
402+
walk_foreign_item_ref(self, ii)
403+
}
381404
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef<'v>) {
382405
walk_impl_item_ref(self, ii)
383406
}
@@ -568,7 +591,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
568591
}
569592
ItemKind::ForeignMod(ref foreign_module) => {
570593
visitor.visit_id(item.hir_id);
571-
walk_list!(visitor, visit_foreign_item, foreign_module.items);
594+
walk_list!(visitor, visit_foreign_item_ref, foreign_module.items);
572595
}
573596
ItemKind::GlobalAsm(_) => {
574597
visitor.visit_id(item.hir_id);
@@ -1012,6 +1035,17 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
10121035
}
10131036
}
10141037

1038+
pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
1039+
visitor: &mut V,
1040+
foreign_item_ref: &'v ForeignItemRef<'v>,
1041+
) {
1042+
// N.B., deliberately force a compilation error if/when new fields are added.
1043+
let ForeignItemRef { id, ident, span: _, ref vis } = *foreign_item_ref;
1044+
visitor.visit_nested_foreign_item(id);
1045+
visitor.visit_ident(ident);
1046+
visitor.visit_vis(vis);
1047+
}
1048+
10151049
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef<'v>) {
10161050
// N.B., deliberately force a compilation error if/when new fields are added.
10171051
let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;

compiler/rustc_hir/src/itemlikevisit.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{ImplItem, Item, TraitItem};
1+
use super::{ForeignItem, ImplItem, Item, TraitItem};
22

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

5253
/// A parallel variant of `ItemLikeVisitor`.
5354
pub trait ParItemLikeVisitor<'hir> {
5455
fn visit_item(&self, item: &'hir Item<'hir>);
5556
fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>);
5657
fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>);
58+
fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>);
5759
}

compiler/rustc_hir/src/stable_hash_impls.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
22

33
use crate::hir::{
4-
BodyId, Expr, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId, Ty,
5-
VisibilityKind,
4+
BodyId, Expr, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem, TraitItemId,
5+
Ty, VisibilityKind,
66
};
77
use crate::hir_id::{HirId, ItemLocalId};
88
use rustc_span::def_id::{DefPathHash, LocalDefId};
@@ -52,6 +52,15 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ImplItemId {
5252
}
5353
}
5454

55+
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ForeignItemId {
56+
type KeyType = (DefPathHash, ItemLocalId);
57+
58+
#[inline]
59+
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
60+
self.hir_id.to_stable_hash_key(hcx)
61+
}
62+
}
63+
5564
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for HirId {
5665
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
5766
hcx.hash_hir_id(*self, hasher)
@@ -77,6 +86,12 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ItemId {
7786
}
7887
}
7988

89+
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ForeignItemId {
90+
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
91+
hcx.hash_reference_to_item(self.hir_id, hasher)
92+
}
93+
}
94+
8095
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
8196
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
8297
hcx.hash_reference_to_item(self.hir_id, hasher)

compiler/rustc_hir_pretty/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub enum Nested {
3636
Item(hir::ItemId),
3737
TraitItem(hir::TraitItemId),
3838
ImplItem(hir::ImplItemId),
39+
ForeignItem(hir::ForeignItemId),
3940
Body(hir::BodyId),
4041
BodyParamPat(hir::BodyId, usize),
4142
}
@@ -56,6 +57,7 @@ impl PpAnn for hir::Crate<'_> {
5657
Nested::Item(id) => state.print_item(self.item(id.id)),
5758
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
5859
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
60+
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
5961
Nested::Body(id) => state.print_expr(&self.body(id).value),
6062
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
6163
}
@@ -70,6 +72,7 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> {
7072
Nested::Item(id) => state.print_item(self.item(id.id)),
7173
Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
7274
Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
75+
Nested::ForeignItem(id) => state.print_foreign_item(self.foreign_item(id)),
7376
Nested::Body(id) => state.print_expr(&self.body(id).value),
7477
Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat),
7578
}
@@ -352,7 +355,7 @@ impl<'a> State<'a> {
352355
pub fn print_foreign_mod(&mut self, nmod: &hir::ForeignMod<'_>, attrs: &[ast::Attribute]) {
353356
self.print_inner_attributes(attrs);
354357
for item in nmod.items {
355-
self.print_foreign_item(item);
358+
self.ann.nested(self, Nested::ForeignItem(item.id));
356359
}
357360
}
358361

compiler/rustc_incremental/src/persist/dirty_clean.rs

+4
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ impl ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
460460
fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) {
461461
self.check_item(item.hir_id, item.span);
462462
}
463+
464+
fn visit_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
465+
self.check_item(item.hir_id, item.span);
466+
}
463467
}
464468

465469
/// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan

compiler/rustc_interface/src/proc_macro_decls.rs

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ impl<'v> ItemLikeVisitor<'v> for Finder<'_> {
3333
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
3434

3535
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
36+
37+
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
3638
}
3739

3840
pub(crate) fn provide(providers: &mut Providers) {

compiler/rustc_metadata/src/foreign_modules.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
2121
_ => return,
2222
};
2323

24-
let foreign_items =
25-
fm.items.iter().map(|it| self.tcx.hir().local_def_id(it.hir_id).to_def_id()).collect();
24+
let foreign_items = fm
25+
.items
26+
.iter()
27+
.map(|it| self.tcx.hir().local_def_id(it.id.hir_id).to_def_id())
28+
.collect();
2629
self.modules.push(ForeignModule {
2730
foreign_items,
2831
def_id: self.tcx.hir().local_def_id(it.hir_id).to_def_id(),
@@ -31,4 +34,5 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
3134

3235
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
3336
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
37+
fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
3438
}

0 commit comments

Comments
 (0)