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>
This commit is contained in:
parent
6a9080b25e
commit
b73b4de982
@ -18,7 +18,6 @@ use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
|
||||
match node {
|
||||
@ -159,12 +158,12 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn items(self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
|
||||
let krate = self.krate();
|
||||
krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() {
|
||||
OwnerNode::Item(item) => Some(item),
|
||||
_ => None,
|
||||
})
|
||||
pub fn items(self) -> impl Iterator<Item = ItemId> + 'hir {
|
||||
self.tcx.hir_crate_items(()).items.iter().map(|id| *id)
|
||||
}
|
||||
|
||||
pub fn par_items(self, f: impl Fn(ItemId) + Sync + Send) {
|
||||
par_for_each_in(self.tcx.hir_crate_items(()).items.to_vec(), f);
|
||||
}
|
||||
|
||||
pub fn def_key(self, def_id: LocalDefId) -> DefKey {
|
||||
@ -677,13 +676,9 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
|
||||
pub fn for_each_module(self, f: impl Fn(LocalDefId)) {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back(CRATE_DEF_ID);
|
||||
|
||||
while let Some(id) = queue.pop_front() {
|
||||
f(id);
|
||||
let items = self.tcx.hir_module_items(id);
|
||||
queue.extend(items.submodules.iter().copied())
|
||||
let crate_items = self.tcx.hir_crate_items(());
|
||||
for module in crate_items.submodules.iter() {
|
||||
f(*module)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1310,3 +1305,69 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
||||
let mut collector = CrateCollector {
|
||||
tcx,
|
||||
submodules: Vec::default(),
|
||||
items: Vec::default(),
|
||||
trait_items: Vec::default(),
|
||||
impl_items: Vec::default(),
|
||||
foreign_items: Vec::default(),
|
||||
};
|
||||
|
||||
tcx.hir().walk_toplevel_module(&mut collector);
|
||||
|
||||
let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
|
||||
collector;
|
||||
|
||||
return ModuleItems {
|
||||
submodules: submodules.into_boxed_slice(),
|
||||
items: items.into_boxed_slice(),
|
||||
trait_items: trait_items.into_boxed_slice(),
|
||||
impl_items: impl_items.into_boxed_slice(),
|
||||
foreign_items: foreign_items.into_boxed_slice(),
|
||||
};
|
||||
|
||||
struct CrateCollector<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
submodules: Vec<LocalDefId>,
|
||||
items: Vec<ItemId>,
|
||||
trait_items: Vec<TraitItemId>,
|
||||
impl_items: Vec<ImplItemId>,
|
||||
foreign_items: Vec<ForeignItemId>,
|
||||
}
|
||||
|
||||
impl<'hir> Visitor<'hir> for CrateCollector<'hir> {
|
||||
type NestedFilter = nested_filter::All;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'hir Item<'hir>) {
|
||||
self.items.push(item.item_id());
|
||||
intravisit::walk_item(self, item)
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) {
|
||||
self.submodules.push(n.owner);
|
||||
intravisit::walk_mod(self, m, n);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) {
|
||||
self.foreign_items.push(item.foreign_item_id());
|
||||
intravisit::walk_foreign_item(self, item)
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) {
|
||||
self.trait_items.push(item.trait_item_id());
|
||||
intravisit::walk_trait_item(self, item)
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) {
|
||||
self.impl_items.push(item.impl_item_id());
|
||||
intravisit::walk_impl_item(self, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
hir.get_module_parent_node(hir.local_def_id_to_hir_id(id))
|
||||
};
|
||||
providers.hir_crate = |tcx, ()| tcx.untracked_crate;
|
||||
providers.hir_crate_items = map::hir_crate_items;
|
||||
providers.crate_hash = map::crate_hash;
|
||||
providers.hir_module_items = map::hir_module_items;
|
||||
providers.hir_owner = |tcx, id| {
|
||||
|
@ -45,6 +45,13 @@ rustc_queries! {
|
||||
desc { "get the crate HIR" }
|
||||
}
|
||||
|
||||
/// All items in the crate.
|
||||
query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
eval_always
|
||||
desc { "get HIR crate items" }
|
||||
}
|
||||
|
||||
/// The items in a module.
|
||||
///
|
||||
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
|
||||
|
@ -2682,7 +2682,8 @@ define_print_and_forward_display! {
|
||||
fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
|
||||
// Iterate all local crate items no matter where they are defined.
|
||||
let hir = tcx.hir();
|
||||
for item in hir.items() {
|
||||
for id in hir.items() {
|
||||
let item = hir.item(id);
|
||||
if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
|
||||
fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
|
||||
let mut map = FxHashMap::<Res, ExistingName>::default();
|
||||
|
||||
for item in cx.tcx.hir().items() {
|
||||
for id in cx.tcx.hir().items() {
|
||||
let item = cx.tcx.hir().item(id);
|
||||
if let ItemKind::Impl(Impl {
|
||||
items,
|
||||
of_trait,
|
||||
|
@ -11,6 +11,19 @@ note: existing `foo` defined here
|
||||
LL | fn foo() {}
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: method's name is the same as an existing method in a trait
|
||||
--> $DIR/same_name_method.rs:34:13
|
||||
|
|
||||
LL | fn clone() {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: existing `clone` defined here
|
||||
--> $DIR/same_name_method.rs:30:18
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
| ^^^^^
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: method's name is the same as an existing method in a trait
|
||||
--> $DIR/same_name_method.rs:44:13
|
||||
|
|
||||
@ -47,18 +60,5 @@ note: existing `foo` defined here
|
||||
LL | impl T1 for S {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: method's name is the same as an existing method in a trait
|
||||
--> $DIR/same_name_method.rs:34:13
|
||||
|
|
||||
LL | fn clone() {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: existing `clone` defined here
|
||||
--> $DIR/same_name_method.rs:30:18
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
| ^^^^^
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user