Skip to content

Commit b73b4de

Browse files
committed
Refactor HIR item-like traversal (part 1)
- Create hir_crate_items query which traverses tcx.hir_crate(()).owners to return a hir::ModuleItems - use tcx.hir_crate_items in tcx.hir().items() to return an iterator of hir::ItemId - add par_items(impl Fn(hir::ItemId)) to traverse all items in parallel Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
1 parent 6a9080b commit b73b4de

File tree

6 files changed

+100
-29
lines changed

6 files changed

+100
-29
lines changed

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_span::source_map::Spanned;
1818
use rustc_span::symbol::{kw, sym, Ident, Symbol};
1919
use rustc_span::Span;
2020
use rustc_target::spec::abi::Abi;
21-
use std::collections::VecDeque;
2221

2322
fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
2423
match node {
@@ -159,12 +158,12 @@ impl<'hir> Map<'hir> {
159158
}
160159
}
161160

162-
pub fn items(self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
163-
let krate = self.krate();
164-
krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() {
165-
OwnerNode::Item(item) => Some(item),
166-
_ => None,
167-
})
161+
pub fn items(self) -> impl Iterator<Item = ItemId> + 'hir {
162+
self.tcx.hir_crate_items(()).items.iter().map(|id| *id)
163+
}
164+
165+
pub fn par_items(self, f: impl Fn(ItemId) + Sync + Send) {
166+
par_for_each_in(self.tcx.hir_crate_items(()).items.to_vec(), f);
168167
}
169168

170169
pub fn def_key(self, def_id: LocalDefId) -> DefKey {
@@ -677,13 +676,9 @@ impl<'hir> Map<'hir> {
677676
}
678677

679678
pub fn for_each_module(self, f: impl Fn(LocalDefId)) {
680-
let mut queue = VecDeque::new();
681-
queue.push_back(CRATE_DEF_ID);
682-
683-
while let Some(id) = queue.pop_front() {
684-
f(id);
685-
let items = self.tcx.hir_module_items(id);
686-
queue.extend(items.submodules.iter().copied())
679+
let crate_items = self.tcx.hir_crate_items(());
680+
for module in crate_items.submodules.iter() {
681+
f(*module)
687682
}
688683
}
689684

@@ -1310,3 +1305,69 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
13101305
}
13111306
}
13121307
}
1308+
1309+
pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
1310+
let mut collector = CrateCollector {
1311+
tcx,
1312+
submodules: Vec::default(),
1313+
items: Vec::default(),
1314+
trait_items: Vec::default(),
1315+
impl_items: Vec::default(),
1316+
foreign_items: Vec::default(),
1317+
};
1318+
1319+
tcx.hir().walk_toplevel_module(&mut collector);
1320+
1321+
let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1322+
collector;
1323+
1324+
return ModuleItems {
1325+
submodules: submodules.into_boxed_slice(),
1326+
items: items.into_boxed_slice(),
1327+
trait_items: trait_items.into_boxed_slice(),
1328+
impl_items: impl_items.into_boxed_slice(),
1329+
foreign_items: foreign_items.into_boxed_slice(),
1330+
};
1331+
1332+
struct CrateCollector<'tcx> {
1333+
tcx: TyCtxt<'tcx>,
1334+
submodules: Vec<LocalDefId>,
1335+
items: Vec<ItemId>,
1336+
trait_items: Vec<TraitItemId>,
1337+
impl_items: Vec<ImplItemId>,
1338+
foreign_items: Vec<ForeignItemId>,
1339+
}
1340+
1341+
impl<'hir> Visitor<'hir> for CrateCollector<'hir> {
1342+
type NestedFilter = nested_filter::All;
1343+
1344+
fn nested_visit_map(&mut self) -> Self::Map {
1345+
self.tcx.hir()
1346+
}
1347+
1348+
fn visit_item(&mut self, item: &'hir Item<'hir>) {
1349+
self.items.push(item.item_id());
1350+
intravisit::walk_item(self, item)
1351+
}
1352+
1353+
fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) {
1354+
self.submodules.push(n.owner);
1355+
intravisit::walk_mod(self, m, n);
1356+
}
1357+
1358+
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
1359+
self.foreign_items.push(item.foreign_item_id());
1360+
intravisit::walk_foreign_item(self, item)
1361+
}
1362+
1363+
fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
1364+
self.trait_items.push(item.trait_item_id());
1365+
intravisit::walk_trait_item(self, item)
1366+
}
1367+
1368+
fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
1369+
self.impl_items.push(item.impl_item_id());
1370+
intravisit::walk_impl_item(self, item)
1371+
}
1372+
}
1373+
}

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ pub fn provide(providers: &mut Providers) {
6868
hir.get_module_parent_node(hir.local_def_id_to_hir_id(id))
6969
};
7070
providers.hir_crate = |tcx, ()| tcx.untracked_crate;
71+
providers.hir_crate_items = map::hir_crate_items;
7172
providers.crate_hash = map::crate_hash;
7273
providers.hir_module_items = map::hir_module_items;
7374
providers.hir_owner = |tcx, id| {

compiler/rustc_middle/src/query/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ rustc_queries! {
4545
desc { "get the crate HIR" }
4646
}
4747

48+
/// All items in the crate.
49+
query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems {
50+
storage(ArenaCacheSelector<'tcx>)
51+
eval_always
52+
desc { "get HIR crate items" }
53+
}
54+
4855
/// The items in a module.
4956
///
5057
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2682,7 +2682,8 @@ define_print_and_forward_display! {
26822682
fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
26832683
// Iterate all local crate items no matter where they are defined.
26842684
let hir = tcx.hir();
2685-
for item in hir.items() {
2685+
for id in hir.items() {
2686+
let item = hir.item(id);
26862687
if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) {
26872688
continue;
26882689
}

src/tools/clippy/clippy_lints/src/same_name_method.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
5050
fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
5151
let mut map = FxHashMap::<Res, ExistingName>::default();
5252

53-
for item in cx.tcx.hir().items() {
53+
for id in cx.tcx.hir().items() {
54+
let item = cx.tcx.hir().item(id);
5455
if let ItemKind::Impl(Impl {
5556
items,
5657
of_trait,

src/tools/clippy/tests/ui/same_name_method.stderr

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ note: existing `foo` defined here
1111
LL | fn foo() {}
1212
| ^^^^^^^^^^^
1313

14+
error: method's name is the same as an existing method in a trait
15+
--> $DIR/same_name_method.rs:34:13
16+
|
17+
LL | fn clone() {}
18+
| ^^^^^^^^^^^^^
19+
|
20+
note: existing `clone` defined here
21+
--> $DIR/same_name_method.rs:30:18
22+
|
23+
LL | #[derive(Clone)]
24+
| ^^^^^
25+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
26+
1427
error: method's name is the same as an existing method in a trait
1528
--> $DIR/same_name_method.rs:44:13
1629
|
@@ -47,18 +60,5 @@ note: existing `foo` defined here
4760
LL | impl T1 for S {}
4861
| ^^^^^^^^^^^^^^^^
4962

50-
error: method's name is the same as an existing method in a trait
51-
--> $DIR/same_name_method.rs:34:13
52-
|
53-
LL | fn clone() {}
54-
| ^^^^^^^^^^^^^
55-
|
56-
note: existing `clone` defined here
57-
--> $DIR/same_name_method.rs:30:18
58-
|
59-
LL | #[derive(Clone)]
60-
| ^^^^^
61-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
62-
6363
error: aborting due to 5 previous errors
6464

0 commit comments

Comments
 (0)