Skip to content

Commit 598bd4f

Browse files
committed
Move HIR traversal queries in rustc_ast_lowering.
1 parent bf37928 commit 598bd4f

File tree

7 files changed

+257
-250
lines changed

7 files changed

+257
-250
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ mod index;
8484
mod item;
8585
mod pat;
8686
mod path;
87+
mod query;
88+
89+
pub use query::provide;
8790

8891
struct LoweringContext<'hir> {
8992
tcx: TyCtxt<'hir>,
+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
use rustc_data_structures::fingerprint::Fingerprint;
2+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3+
use rustc_data_structures::svh::Svh;
4+
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
5+
use rustc_hir::intravisit::{self, Visitor};
6+
use rustc_hir::{ForeignItem, ImplItem, Item, ItemKind, Mod, TraitItem};
7+
use rustc_hir::{ForeignItemId, HirId, ImplItemId, ItemId, ModuleItems, TraitItemId};
8+
use rustc_middle::hir::nested_filter;
9+
use rustc_middle::ty::query::Providers;
10+
use rustc_middle::ty::TyCtxt;
11+
use rustc_span::Span;
12+
13+
pub fn provide(providers: &mut Providers) {
14+
*providers = Providers { crate_hash, hir_module_items, hir_crate_items, ..*providers };
15+
}
16+
17+
fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
18+
debug_assert_eq!(crate_num, LOCAL_CRATE);
19+
let krate = tcx.hir_crate(());
20+
let hir_body_hash = krate.hir_hash;
21+
22+
let upstream_crates = upstream_crates(tcx);
23+
24+
// We hash the final, remapped names of all local source files so we
25+
// don't have to include the path prefix remapping commandline args.
26+
// If we included the full mapping in the SVH, we could only have
27+
// reproducible builds by compiling from the same directory. So we just
28+
// hash the result of the mapping instead of the mapping itself.
29+
let mut source_file_names: Vec<_> = tcx
30+
.sess
31+
.source_map()
32+
.files()
33+
.iter()
34+
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
35+
.map(|source_file| source_file.name_hash)
36+
.collect();
37+
38+
source_file_names.sort_unstable();
39+
40+
let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
41+
let mut stable_hasher = StableHasher::new();
42+
hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
43+
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
44+
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
45+
if tcx.sess.opts.debugging_opts.incremental_relative_spans {
46+
let definitions = tcx.definitions_untracked();
47+
let mut owner_spans: Vec<_> = krate
48+
.owners
49+
.iter_enumerated()
50+
.filter_map(|(def_id, info)| {
51+
let _ = info.as_owner()?;
52+
let def_path_hash = definitions.def_path_hash(def_id);
53+
let span = definitions.def_span(def_id);
54+
debug_assert_eq!(span.parent(), None);
55+
Some((def_path_hash, span))
56+
})
57+
.collect();
58+
owner_spans.sort_unstable_by_key(|bn| bn.0);
59+
owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
60+
}
61+
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
62+
tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
63+
// Hash visibility information since it does not appear in HIR.
64+
let resolutions = tcx.resolutions(());
65+
resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
66+
resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher);
67+
stable_hasher.finish()
68+
});
69+
70+
Svh::new(crate_hash.to_smaller_hash())
71+
}
72+
73+
fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
74+
let mut upstream_crates: Vec<_> = tcx
75+
.crates(())
76+
.iter()
77+
.map(|&cnum| {
78+
let stable_crate_id = tcx.stable_crate_id(cnum);
79+
let hash = tcx.crate_hash(cnum);
80+
(stable_crate_id, hash)
81+
})
82+
.collect();
83+
upstream_crates.sort_unstable_by_key(|&(stable_crate_id, _)| stable_crate_id);
84+
upstream_crates
85+
}
86+
87+
fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> ModuleItems {
88+
let mut collector = ModuleCollector {
89+
tcx,
90+
submodules: Vec::default(),
91+
items: Vec::default(),
92+
trait_items: Vec::default(),
93+
impl_items: Vec::default(),
94+
foreign_items: Vec::default(),
95+
};
96+
97+
let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id);
98+
collector.visit_mod(hir_mod, span, hir_id);
99+
100+
let ModuleCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
101+
collector;
102+
return ModuleItems {
103+
submodules: submodules.into_boxed_slice(),
104+
items: items.into_boxed_slice(),
105+
trait_items: trait_items.into_boxed_slice(),
106+
impl_items: impl_items.into_boxed_slice(),
107+
foreign_items: foreign_items.into_boxed_slice(),
108+
};
109+
110+
struct ModuleCollector<'tcx> {
111+
tcx: TyCtxt<'tcx>,
112+
submodules: Vec<LocalDefId>,
113+
items: Vec<ItemId>,
114+
trait_items: Vec<TraitItemId>,
115+
impl_items: Vec<ImplItemId>,
116+
foreign_items: Vec<ForeignItemId>,
117+
}
118+
119+
impl<'hir> Visitor<'hir> for ModuleCollector<'hir> {
120+
type NestedFilter = nested_filter::All;
121+
122+
fn nested_visit_map(&mut self) -> Self::Map {
123+
self.tcx.hir()
124+
}
125+
126+
fn visit_item(&mut self, item: &'hir Item<'hir>) {
127+
self.items.push(item.item_id());
128+
if let ItemKind::Mod(..) = item.kind {
129+
// If this declares another module, do not recurse inside it.
130+
self.submodules.push(item.def_id);
131+
} else {
132+
intravisit::walk_item(self, item)
133+
}
134+
}
135+
136+
fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
137+
self.trait_items.push(item.trait_item_id());
138+
intravisit::walk_trait_item(self, item)
139+
}
140+
141+
fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
142+
self.impl_items.push(item.impl_item_id());
143+
intravisit::walk_impl_item(self, item)
144+
}
145+
146+
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
147+
self.foreign_items.push(item.foreign_item_id());
148+
intravisit::walk_foreign_item(self, item)
149+
}
150+
}
151+
}
152+
153+
fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
154+
let mut collector = CrateCollector {
155+
tcx,
156+
submodules: Vec::default(),
157+
items: Vec::default(),
158+
trait_items: Vec::default(),
159+
impl_items: Vec::default(),
160+
foreign_items: Vec::default(),
161+
};
162+
163+
tcx.hir().walk_toplevel_module(&mut collector);
164+
165+
let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
166+
collector;
167+
168+
return ModuleItems {
169+
submodules: submodules.into_boxed_slice(),
170+
items: items.into_boxed_slice(),
171+
trait_items: trait_items.into_boxed_slice(),
172+
impl_items: impl_items.into_boxed_slice(),
173+
foreign_items: foreign_items.into_boxed_slice(),
174+
};
175+
176+
struct CrateCollector<'tcx> {
177+
tcx: TyCtxt<'tcx>,
178+
submodules: Vec<LocalDefId>,
179+
items: Vec<ItemId>,
180+
trait_items: Vec<TraitItemId>,
181+
impl_items: Vec<ImplItemId>,
182+
foreign_items: Vec<ForeignItemId>,
183+
}
184+
185+
impl<'hir> Visitor<'hir> for CrateCollector<'hir> {
186+
type NestedFilter = nested_filter::All;
187+
188+
fn nested_visit_map(&mut self) -> Self::Map {
189+
self.tcx.hir()
190+
}
191+
192+
fn visit_item(&mut self, item: &'hir Item<'hir>) {
193+
self.items.push(item.item_id());
194+
intravisit::walk_item(self, item)
195+
}
196+
197+
fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) {
198+
self.submodules.push(n.owner);
199+
intravisit::walk_mod(self, m, n);
200+
}
201+
202+
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
203+
self.foreign_items.push(item.foreign_item_id());
204+
intravisit::walk_foreign_item(self, item)
205+
}
206+
207+
fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
208+
self.trait_items.push(item.trait_item_id());
209+
intravisit::walk_trait_item(self, item)
210+
}
211+
212+
fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
213+
self.impl_items.push(item.impl_item_id());
214+
intravisit::walk_impl_item(self, item)
215+
}
216+
}
217+
}

compiler/rustc_hir/src/hir.rs

+29
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,35 @@ impl<T> MaybeOwner<T> {
796796
}
797797
}
798798

799+
/// Gather the LocalDefId for each item-like within a module, including items contained within
800+
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
801+
#[derive(Debug, HashStable_Generic)]
802+
pub struct ModuleItems {
803+
pub submodules: Box<[LocalDefId]>,
804+
pub items: Box<[ItemId]>,
805+
pub trait_items: Box<[TraitItemId]>,
806+
pub impl_items: Box<[ImplItemId]>,
807+
pub foreign_items: Box<[ForeignItemId]>,
808+
}
809+
810+
impl ModuleItems {
811+
pub fn items(&self) -> impl Iterator<Item = ItemId> + '_ {
812+
self.items.iter().copied()
813+
}
814+
815+
pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> + '_ {
816+
self.trait_items.iter().copied()
817+
}
818+
819+
pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> + '_ {
820+
self.impl_items.iter().copied()
821+
}
822+
823+
pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> + '_ {
824+
self.foreign_items.iter().copied()
825+
}
826+
}
827+
799828
/// The top-level data structure that stores the entire contents of
800829
/// the crate currently being compiled.
801830
///

compiler/rustc_interface/src/passes.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, PResult};
1515
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
1616
use rustc_hir::def_id::{LocalDefId, StableCrateId, LOCAL_CRATE};
1717
use rustc_hir::definitions::Definitions;
18-
use rustc_hir::{Crate, MaybeOwner, OwnerInfo};
18+
use rustc_hir::Crate;
1919
use rustc_index::vec::{Idx, IndexVec};
2020
use rustc_lint::{EarlyCheckNode, LintStore};
2121
use rustc_metadata::creader::CStore;
@@ -525,11 +525,6 @@ fn hir_crate<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> Crate<'tcx> {
525525
hir_crate
526526
}
527527

528-
/// Lower AST to HIR.
529-
fn lower_to_hir<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> MaybeOwner<&'tcx OwnerInfo<'tcx>> {
530-
rustc_ast_lowering::lower_to_hir(tcx, def_id, rustc_parse::nt_to_tokenstream)
531-
}
532-
533528
// Returns all the paths that correspond to generated files.
534529
fn generated_output_paths(
535530
sess: &Session,
@@ -795,7 +790,9 @@ pub static DEFAULT_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| {
795790
let providers = &mut Providers::default();
796791
providers.analysis = analysis;
797792
providers.hir_crate = hir_crate;
798-
providers.lower_to_hir = lower_to_hir;
793+
providers.lower_to_hir =
794+
|tcx, def_id| rustc_ast_lowering::lower_to_hir(tcx, def_id, rustc_parse::nt_to_tokenstream);
795+
rustc_ast_lowering::provide(providers);
799796
proc_macro_decls::provide(providers);
800797
rustc_const_eval::provide(providers);
801798
rustc_middle::hir::provide(providers);

0 commit comments

Comments
 (0)