about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMiguel Guarniz <mi9uel9@gmail.com>2022-04-03 15:50:33 -0400
committerMiguel Guarniz <mi9uel9@gmail.com>2022-04-08 11:59:59 -0400
commitb73b4de982a16e8819e804cb648ff3ea63d22028 (patch)
treebbf7b76b289b1f76aa31df21f870c9af8d6258c1
parent6a9080b25e73d26aae94c3f6a13b31de58e66b5a (diff)
downloadrust-b73b4de982a16e8819e804cb648ff3ea63d22028.tar.gz
rust-b73b4de982a16e8819e804cb648ff3ea63d22028.zip
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>
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs89
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs3
-rw-r--r--src/tools/clippy/tests/ui/same_name_method.stderr26
6 files changed, 100 insertions, 29 deletions
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 561653f3beb..79bbf591534 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -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)
+        }
+    }
+}
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index a9e22d16ee0..fcce2d005d7 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -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| {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 89761bf4e27..6733e0f7f3c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -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`.
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 9a9c529f245..61f078c0e48 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -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;
         }
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 22b45896955..c7606186714 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -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,
diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr
index c32c3dd9880..cf06eb32e0c 100644
--- a/src/tools/clippy/tests/ui/same_name_method.stderr
+++ b/src/tools/clippy/tests/ui/same_name_method.stderr
@@ -12,6 +12,19 @@ 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
    |
 LL |             fn foo() {}
@@ -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