about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir/src/target.rs25
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs41
-rw-r--r--compiler/rustc_interface/src/proc_macro_decls.rs28
-rw-r--r--compiler/rustc_metadata/src/foreign_modules.rs34
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs58
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs89
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs19
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs10
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs115
-rw-r--r--compiler/rustc_passes/src/lang_items.rs51
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs56
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs39
-rw-r--r--compiler/rustc_typeck/src/check_unused.rs118
-rw-r--r--compiler/rustc_typeck/src/outlives/implicit_infer.rs109
16 files changed, 414 insertions, 406 deletions
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 70d9db4a84b..96dd00ec5cf 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -7,6 +7,7 @@
 use crate::hir;
 use crate::{Item, ItemKind, TraitItem, TraitItemKind};
 
+use crate::def::DefKind;
 use std::fmt::{self, Display};
 
 #[derive(Copy, Clone, PartialEq, Debug)]
@@ -130,6 +131,30 @@ impl Target {
         }
     }
 
+    // FIXME: For now, should only be used with def_kinds from ItemIds
+    pub fn from_def_kind(def_kind: DefKind) -> Target {
+        match def_kind {
+            DefKind::ExternCrate => Target::ExternCrate,
+            DefKind::Use => Target::Use,
+            DefKind::Static(..) => Target::Static,
+            DefKind::Const => Target::Const,
+            DefKind::Fn => Target::Fn,
+            DefKind::Macro(..) => Target::MacroDef,
+            DefKind::Mod => Target::Mod,
+            DefKind::ForeignMod => Target::ForeignMod,
+            DefKind::GlobalAsm => Target::GlobalAsm,
+            DefKind::TyAlias => Target::TyAlias,
+            DefKind::OpaqueTy => Target::OpaqueTy,
+            DefKind::Enum => Target::Enum,
+            DefKind::Struct => Target::Struct,
+            DefKind::Union => Target::Union,
+            DefKind::Trait => Target::Trait,
+            DefKind::TraitAlias => Target::TraitAlias,
+            DefKind::Impl => Target::Impl,
+            _ => panic!("impossible case reached"),
+        }
+    }
+
     pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
         match trait_item.kind {
             TraitItemKind::Const(..) => Target::AssocConst,
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 8a4ed02f6ae..aaf24636598 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -24,7 +24,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::Node as HirNode;
 use rustc_hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind};
 use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeExt};
@@ -147,7 +146,24 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
 
     tcx.dep_graph.with_ignore(|| {
         let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() };
-        tcx.hir().visit_all_item_likes(&mut dirty_clean_visitor);
+
+        let crate_items = tcx.hir_crate_items(());
+
+        for id in crate_items.items() {
+            dirty_clean_visitor.check_item(id.def_id);
+        }
+
+        for id in crate_items.trait_items() {
+            dirty_clean_visitor.check_item(id.def_id);
+        }
+
+        for id in crate_items.impl_items() {
+            dirty_clean_visitor.check_item(id.def_id);
+        }
+
+        for id in crate_items.foreign_items() {
+            dirty_clean_visitor.check_item(id.def_id);
+        }
 
         let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
         tcx.hir().walk_attributes(&mut all_attrs);
@@ -365,7 +381,8 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
         }
     }
 
-    fn check_item(&mut self, item_id: LocalDefId, item_span: Span) {
+    fn check_item(&mut self, item_id: LocalDefId) {
+        let item_span = self.tcx.def_span(item_id.to_def_id());
         let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id());
         for attr in self.tcx.get_attrs(item_id.to_def_id()).iter() {
             let Some(assertion) = self.assertion_maybe(item_id, attr) else {
@@ -388,24 +405,6 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
     }
 }
 
-impl<'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        self.check_item(item.def_id, item.span);
-    }
-
-    fn visit_trait_item(&mut self, item: &hir::TraitItem<'_>) {
-        self.check_item(item.def_id, item.span);
-    }
-
-    fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) {
-        self.check_item(item.def_id, item.span);
-    }
-
-    fn visit_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
-        self.check_item(item.def_id, item.span);
-    }
-}
-
 /// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have
 /// a cfg flag called `foo`.
 fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs
index c0316ce58d2..5371c513d29 100644
--- a/compiler/rustc_interface/src/proc_macro_decls.rs
+++ b/compiler/rustc_interface/src/proc_macro_decls.rs
@@ -1,35 +1,25 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
 fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
     let mut finder = Finder { tcx, decls: None };
-    tcx.hir().visit_all_item_likes(&mut finder);
 
-    finder.decls.map(|id| tcx.hir().local_def_id(id))
-}
-
-struct Finder<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    decls: Option<hir::HirId>,
-}
-
-impl<'v> ItemLikeVisitor<'v> for Finder<'_> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        let attrs = self.tcx.hir().attrs(item.hir_id());
-        if self.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
-            self.decls = Some(item.hir_id());
+    for id in tcx.hir().items() {
+        let attrs = finder.tcx.hir().attrs(id.hir_id());
+        if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) {
+            finder.decls = Some(id.def_id);
         }
     }
 
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
+    finder.decls
+}
 
-    fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
+struct Finder<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    decls: Option<hir::def_id::LocalDefId>,
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs
index c4ee1e19128..97fcbeb4ccc 100644
--- a/compiler/rustc_metadata/src/foreign_modules.rs
+++ b/compiler/rustc_metadata/src/foreign_modules.rs
@@ -1,29 +1,19 @@
 use rustc_hir as hir;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::cstore::ForeignModule;
 
 crate fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
-    let mut collector = Collector { modules: Vec::new() };
-    tcx.hir().visit_all_item_likes(&mut collector);
-    collector.modules
-}
-
-struct Collector {
-    modules: Vec<ForeignModule>,
-}
-
-impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
-    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
-        let hir::ItemKind::ForeignMod { items, .. } = it.kind else {
-            return;
-        };
-
-        let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
-        self.modules.push(ForeignModule { foreign_items, def_id: it.def_id.to_def_id() });
+    let mut modules = Vec::new();
+    for id in tcx.hir().items() {
+        if !matches!(tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) {
+            continue;
+        }
+        let item = tcx.hir().item(id);
+        if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
+            let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
+            modules.push(ForeignModule { foreign_items, def_id: id.def_id.to_def_id() });
+        }
     }
-
-    fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
-    fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
-    fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
+    modules
 }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 1cbfb0bd554..43b6ecee794 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -3,7 +3,7 @@ use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_hir::def::DefKind;
 use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
 use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib};
 use rustc_session::parse::feature_err;
@@ -15,7 +15,9 @@ use rustc_target::spec::abi::Abi;
 
 crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
     let mut collector = Collector { tcx, libs: Vec::new() };
-    tcx.hir().visit_all_item_likes(&mut collector);
+    for id in tcx.hir().items() {
+        collector.process_item(id);
+    }
     collector.process_command_line();
     collector.libs
 }
@@ -32,8 +34,13 @@ struct Collector<'tcx> {
     libs: Vec<NativeLib>,
 }
 
-impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
-    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
+impl<'tcx> Collector<'tcx> {
+    fn process_item(&mut self, id: rustc_hir::ItemId) {
+        if !matches!(self.tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) {
+            return;
+        }
+
+        let it = self.tcx.hir().item(id);
         let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
             return;
         };
@@ -252,12 +259,6 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
         }
     }
 
-    fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {}
-    fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
-    fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {}
-}
-
-impl Collector<'_> {
     fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLib) {
         if lib.name.as_ref().map_or(false, |&s| s == kw::Empty) {
             match span {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 732e7ef8a23..6a8d4e03754 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1787,10 +1787,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         debug!("EncodeContext::encode_traits_and_impls()");
         empty_proc_macro!(self);
         let tcx = self.tcx;
-        let mut visitor = ImplsVisitor { tcx, impls: FxHashMap::default() };
-        tcx.hir().visit_all_item_likes(&mut visitor);
+        let mut fx_hash_map: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> =
+            FxHashMap::default();
 
-        let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
+        for id in tcx.hir().items() {
+            if matches!(tcx.hir().def_kind(id.def_id), DefKind::Impl) {
+                if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) {
+                    let simplified_self_ty = fast_reject::simplify_type(
+                        self.tcx,
+                        trait_ref.self_ty(),
+                        TreatParams::AsPlaceholders,
+                    );
+
+                    fx_hash_map
+                        .entry(trait_ref.def_id)
+                        .or_default()
+                        .push((id.def_id.local_def_index, simplified_self_ty));
+                }
+            }
+        }
+
+        let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect();
 
         // Bring everything into deterministic order for hashing
         all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
@@ -2053,41 +2070,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 }
 
-struct ImplsVisitor<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    impls: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>>,
-}
-
-impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        match item.kind {
-            hir::ItemKind::Impl(..) => {
-                if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
-                    let simplified_self_ty = fast_reject::simplify_type(
-                        self.tcx,
-                        trait_ref.self_ty(),
-                        TreatParams::AsPlaceholders,
-                    );
-
-                    self.impls
-                        .entry(trait_ref.def_id)
-                        .or_default()
-                        .push((item.def_id.local_def_index, simplified_self_ty));
-                }
-            }
-            _ => {}
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem<'v>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem<'v>) {
-        // handled in `visit_item` above
-    }
-
-    fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
-}
-
 /// Used to prefetch queries which will be needed later by metadata encoding.
 /// Only a subset of the queries are actually prefetched to keep this code smaller.
 fn prefetch_mir(tcx: TyCtxt<'_>) {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 08cd40f38ef..d74759e31a2 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().copied()
+    }
+
+    pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) {
+        par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id));
     }
 
     pub fn def_key(self, def_id: LocalDefId) -> DefKey {
@@ -675,13 +674,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)
         }
     }
 
@@ -1308,3 +1303,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..f18067145dd 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -45,6 +45,24 @@ pub struct ModuleItems {
     foreign_items: Box<[ForeignItemId]>,
 }
 
+impl ModuleItems {
+    pub fn items(&self) -> impl Iterator<Item = ItemId> + '_ {
+        self.items.iter().copied()
+    }
+
+    pub fn trait_items(&self) -> impl Iterator<Item = TraitItemId> + '_ {
+        self.trait_items.iter().copied()
+    }
+
+    pub fn impl_items(&self) -> impl Iterator<Item = ImplItemId> + '_ {
+        self.impl_items.iter().copied()
+    }
+
+    pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> + '_ {
+        self.foreign_items.iter().copied()
+    }
+}
+
 impl<'tcx> TyCtxt<'tcx> {
     #[inline(always)]
     pub fn hir(self) -> map::Map<'tcx> {
@@ -68,6 +86,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 f38ade1076e..999cb9f30b8 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 4379adb604e..cac46ba25fe 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -8,7 +8,6 @@ use rustc_hir as hir;
 use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
 use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
-use rustc_hir::ItemKind;
 use rustc_session::config::TrimmedDefPaths;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
 use rustc_span::symbol::{kw, Ident, Symbol};
@@ -2678,8 +2677,13 @@ 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() {
-        if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) {
+    for id in hir.items() {
+        if matches!(hir.def_kind(id.def_id), DefKind::Use) {
+            continue;
+        }
+
+        let item = hir.item(id);
+        if item.ident.name == kw::Empty {
             continue;
         }
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index fdb14e45d98..0e0a4fbc215 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -181,8 +181,8 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::mir::interpret::{AllocId, ConstValue};
@@ -327,11 +327,19 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
 
         debug!("collect_roots: entry_fn = {:?}", entry_fn);
 
-        let mut visitor = RootCollector { tcx, mode, entry_fn, output: &mut roots };
+        let mut collector = RootCollector { tcx, mode, entry_fn, output: &mut roots };
 
-        tcx.hir().visit_all_item_likes(&mut visitor);
+        let crate_items = tcx.hir_crate_items(());
 
-        visitor.push_extra_entry_roots();
+        for id in crate_items.items() {
+            collector.process_item(id);
+        }
+
+        for id in crate_items.impl_items() {
+            collector.process_impl_item(id);
+        }
+
+        collector.push_extra_entry_roots();
     }
 
     // We can only codegen items that are instantiable - items all of
@@ -1159,87 +1167,74 @@ struct RootCollector<'a, 'tcx> {
     entry_fn: Option<(DefId, EntryFnType)>,
 }
 
-impl<'v> ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
-    fn visit_item(&mut self, item: &'v hir::Item<'v>) {
-        match item.kind {
-            hir::ItemKind::ExternCrate(..)
-            | hir::ItemKind::Use(..)
-            | hir::ItemKind::Macro(..)
-            | hir::ItemKind::ForeignMod { .. }
-            | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::Trait(..)
-            | hir::ItemKind::TraitAlias(..)
-            | hir::ItemKind::OpaqueTy(..)
-            | hir::ItemKind::Mod(..) => {
-                // Nothing to do, just keep recursing.
-            }
-
-            hir::ItemKind::Impl { .. } => {
-                if self.mode == MonoItemCollectionMode::Eager {
-                    create_mono_items_for_default_impls(self.tcx, item, self.output);
-                }
-            }
-
-            hir::ItemKind::Enum(_, ref generics)
-            | hir::ItemKind::Struct(_, ref generics)
-            | hir::ItemKind::Union(_, ref generics) => {
-                if generics.params.is_empty() {
-                    if self.mode == MonoItemCollectionMode::Eager {
-                        debug!(
-                            "RootCollector: ADT drop-glue for {}",
-                            self.tcx.def_path_str(item.def_id.to_def_id())
-                        );
-
-                        let ty = Instance::new(item.def_id.to_def_id(), InternalSubsts::empty())
-                            .ty(self.tcx, ty::ParamEnv::reveal_all());
-                        visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
+impl<'v> RootCollector<'_, 'v> {
+    fn process_item(&mut self, id: hir::ItemId) {
+        match self.tcx.hir().def_kind(id.def_id) {
+            DefKind::Enum | DefKind::Struct | DefKind::Union => {
+                let item = self.tcx.hir().item(id);
+                match item.kind {
+                    hir::ItemKind::Enum(_, ref generics)
+                    | hir::ItemKind::Struct(_, ref generics)
+                    | hir::ItemKind::Union(_, ref generics) => {
+                        if generics.params.is_empty() {
+                            if self.mode == MonoItemCollectionMode::Eager {
+                                debug!(
+                                    "RootCollector: ADT drop-glue for {}",
+                                    self.tcx.def_path_str(item.def_id.to_def_id())
+                                );
+
+                                let ty =
+                                    Instance::new(item.def_id.to_def_id(), InternalSubsts::empty())
+                                        .ty(self.tcx, ty::ParamEnv::reveal_all());
+                                visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
+                            }
+                        }
                     }
+                    _ => bug!(),
                 }
             }
-            hir::ItemKind::GlobalAsm(..) => {
+            DefKind::GlobalAsm => {
                 debug!(
                     "RootCollector: ItemKind::GlobalAsm({})",
-                    self.tcx.def_path_str(item.def_id.to_def_id())
+                    self.tcx.def_path_str(id.def_id.to_def_id())
                 );
-                self.output.push(dummy_spanned(MonoItem::GlobalAsm(item.item_id())));
+                self.output.push(dummy_spanned(MonoItem::GlobalAsm(id)));
             }
-            hir::ItemKind::Static(..) => {
+            DefKind::Static(..) => {
                 debug!(
                     "RootCollector: ItemKind::Static({})",
-                    self.tcx.def_path_str(item.def_id.to_def_id())
+                    self.tcx.def_path_str(id.def_id.to_def_id())
                 );
-                self.output.push(dummy_spanned(MonoItem::Static(item.def_id.to_def_id())));
+                self.output.push(dummy_spanned(MonoItem::Static(id.def_id.to_def_id())));
             }
-            hir::ItemKind::Const(..) => {
+            DefKind::Const => {
                 // const items only generate mono items if they are
                 // actually used somewhere. Just declaring them is insufficient.
 
                 // but even just declaring them must collect the items they refer to
-                if let Ok(val) = self.tcx.const_eval_poly(item.def_id.to_def_id()) {
+                if let Ok(val) = self.tcx.const_eval_poly(id.def_id.to_def_id()) {
                     collect_const_value(self.tcx, val, &mut self.output);
                 }
             }
-            hir::ItemKind::Fn(..) => {
-                self.push_if_root(item.def_id);
+            DefKind::Impl => {
+                if self.mode == MonoItemCollectionMode::Eager {
+                    let item = self.tcx.hir().item(id);
+                    create_mono_items_for_default_impls(self.tcx, item, self.output);
+                }
+            }
+            DefKind::Fn => {
+                self.push_if_root(id.def_id);
             }
+            _ => {}
         }
     }
 
-    fn visit_trait_item(&mut self, _: &'v hir::TraitItem<'v>) {
-        // Even if there's a default body with no explicit generics,
-        // it's still generic over some `Self: Trait`, so not a root.
-    }
-
-    fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
-        if let hir::ImplItemKind::Fn(hir::FnSig { .. }, _) = ii.kind {
-            self.push_if_root(ii.def_id);
+    fn process_impl_item(&mut self, id: hir::ImplItemId) {
+        if matches!(self.tcx.hir().def_kind(id.def_id), DefKind::AssocFn) {
+            self.push_if_root(id.def_id);
         }
     }
 
-    fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
-}
-
-impl<'v> RootCollector<'_, 'v> {
     fn is_root(&self, def_id: LocalDefId) -> bool {
         !item_requires_monomorphization(self.tcx, def_id)
             && match self.mode {
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 0c934ecc913..18d9bdf8e17 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -12,8 +12,8 @@ use crate::weak_lang_items;
 
 use rustc_errors::{pluralize, struct_span_err};
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::lang_items::{extract, GenericRequirement, ITEM_REFS};
 use rustc_hir::{HirId, LangItem, LanguageItems, Target};
 use rustc_middle::ty::TyCtxt;
@@ -27,28 +27,6 @@ struct LanguageItemCollector<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
-impl<'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        self.check_for_lang(Target::from_item(item), item.hir_id());
-
-        if let hir::ItemKind::Enum(def, ..) = &item.kind {
-            for variant in def.variants {
-                self.check_for_lang(Target::Variant, variant.id);
-            }
-        }
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
-        self.check_for_lang(Target::from_trait_item(trait_item), trait_item.hir_id())
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
-        self.check_for_lang(target_from_impl_item(self.tcx, impl_item), impl_item.hir_id())
-    }
-
-    fn visit_foreign_item(&mut self, _: &hir::ForeignItem<'_>) {}
-}
-
 impl<'tcx> LanguageItemCollector<'tcx> {
     fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> {
         LanguageItemCollector { tcx, items: LanguageItems::new() }
@@ -259,7 +237,32 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
     }
 
     // Collect lang items in this crate.
-    tcx.hir().visit_all_item_likes(&mut collector);
+    let crate_items = tcx.hir_crate_items(());
+
+    for id in crate_items.items() {
+        collector.check_for_lang(Target::from_def_kind(tcx.hir().def_kind(id.def_id)), id.hir_id());
+
+        if matches!(tcx.hir().def_kind(id.def_id), DefKind::Enum) {
+            let item = tcx.hir().item(id);
+            if let hir::ItemKind::Enum(def, ..) = &item.kind {
+                for variant in def.variants {
+                    collector.check_for_lang(Target::Variant, variant.id);
+                }
+            }
+        }
+    }
+
+    // FIXME: avoid calling trait_item() when possible
+    for id in crate_items.trait_items() {
+        let item = tcx.hir().trait_item(id);
+        collector.check_for_lang(Target::from_trait_item(item), item.hir_id())
+    }
+
+    // FIXME: avoid calling impl_item() when possible
+    for id in crate_items.impl_items() {
+        let item = tcx.hir().impl_item(id);
+        collector.check_for_lang(target_from_impl_item(tcx, item), item.hir_id())
+    }
 
     // Extract out the found lang items.
     let LanguageItemCollector { mut items, .. } = collector;
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 6b73c950119..5411946343b 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -2,20 +2,11 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
-use rustc_hir as hir;
-use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::lang_items::{self, LangItem};
 use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS;
 use rustc_middle::middle::lang_items::required;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::CrateType;
-use rustc_span::symbol::Symbol;
-use rustc_span::Span;
-
-struct Context<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    items: &'a mut lang_items::LanguageItems,
-}
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
@@ -30,10 +21,28 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem
         items.missing.push(LangItem::EhCatchTypeinfo);
     }
 
-    {
-        let mut cx = Context { tcx, items };
-        tcx.hir().visit_all_item_likes(&mut cx.as_deep_visitor());
+    let crate_items = tcx.hir_crate_items(());
+    for id in crate_items.foreign_items() {
+        let attrs = tcx.hir().attrs(id.hir_id());
+        if let Some((lang_item, _)) = lang_items::extract(attrs) {
+            if let Some(&item) = WEAK_ITEMS_REFS.get(&lang_item) {
+                if items.require(item).is_err() {
+                    items.missing.push(item);
+                }
+            } else {
+                let span = tcx.def_span(id.def_id);
+                struct_span_err!(
+                    tcx.sess,
+                    span,
+                    E0264,
+                    "unknown external lang item: `{}`",
+                    lang_item
+                )
+                .emit();
+            }
+        }
     }
+
     verify(tcx, items);
 }
 
@@ -80,26 +89,3 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
         }
     }
 }
-
-impl<'a, 'tcx> Context<'a, 'tcx> {
-    fn register(&mut self, name: Symbol, span: Span) {
-        if let Some(&item) = WEAK_ITEMS_REFS.get(&name) {
-            if self.items.require(item).is_err() {
-                self.items.missing.push(item);
-            }
-        } else {
-            struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name)
-                .emit();
-        }
-    }
-}
-
-impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
-    fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
-        let attrs = self.tcx.hir().attrs(i.hir_id());
-        if let Some((lang_item, _)) = lang_items::extract(attrs) {
-            self.register(lang_item, i.span);
-        }
-        intravisit::walk_foreign_item(self, i)
-    }
-}
diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs
index 611943652a6..37d1cffa2a5 100644
--- a/compiler/rustc_symbol_mangling/src/test.rs
+++ b/compiler/rustc_symbol_mangling/src/test.rs
@@ -4,7 +4,6 @@
 //! def-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
-use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{subst::InternalSubsts, Instance, TyCtxt};
@@ -22,8 +21,24 @@ pub fn report_symbol_names(tcx: TyCtxt<'_>) {
     }
 
     tcx.dep_graph.with_ignore(|| {
-        let mut visitor = SymbolNamesTest { tcx };
-        tcx.hir().visit_all_item_likes(&mut visitor);
+        let mut symbol_names = SymbolNamesTest { tcx };
+        let crate_items = tcx.hir_crate_items(());
+
+        for id in crate_items.items() {
+            symbol_names.process_attrs(id.def_id);
+        }
+
+        for id in crate_items.trait_items() {
+            symbol_names.process_attrs(id.def_id);
+        }
+
+        for id in crate_items.impl_items() {
+            symbol_names.process_attrs(id.def_id);
+        }
+
+        for id in crate_items.foreign_items() {
+            symbol_names.process_attrs(id.def_id);
+        }
     })
 }
 
@@ -58,21 +73,3 @@ impl SymbolNamesTest<'_> {
         }
     }
 }
-
-impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'tcx> {
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        self.process_attrs(item.def_id);
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        self.process_attrs(trait_item.def_id);
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        self.process_attrs(impl_item.def_id);
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &'tcx hir::ForeignItem<'tcx>) {
-        self.process_attrs(foreign_item.def_id);
-    }
-}
diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 1826c3f5f7f..4f792fa25a1 100644
--- a/compiler/rustc_typeck/src/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
@@ -1,72 +1,58 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint;
 use rustc_span::{Span, Symbol};
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
-    let mut used_trait_imports = FxHashSet::default();
+    let mut used_trait_imports: FxHashSet<LocalDefId> = FxHashSet::default();
+
     for item_def_id in tcx.hir().body_owners() {
         let imports = tcx.used_trait_imports(item_def_id);
         debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
         used_trait_imports.extend(imports.iter());
     }
 
-    let mut visitor = CheckVisitor { tcx, used_trait_imports };
-    tcx.hir().visit_all_item_likes(&mut visitor);
-
-    unused_crates_lint(tcx);
-}
-
-impl<'tcx> ItemLikeVisitor<'_> for CheckVisitor<'tcx> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        if item.vis.node.is_pub() || item.span.is_dummy() {
-            return;
-        }
-        if let hir::ItemKind::Use(path, _) = item.kind {
-            self.check_import(item.item_id(), path.span);
+    for id in tcx.hir().items() {
+        if matches!(tcx.hir().def_kind(id.def_id), DefKind::Use) {
+            let item = tcx.hir().item(id);
+            if item.vis.node.is_pub() || item.span.is_dummy() {
+                continue;
+            }
+            if let hir::ItemKind::Use(path, _) = item.kind {
+                check_import(tcx, &mut used_trait_imports, item.item_id(), path.span);
+            }
         }
     }
 
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
-
-    fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
+    unused_crates_lint(tcx);
 }
 
-struct CheckVisitor<'tcx> {
+fn check_import<'tcx>(
     tcx: TyCtxt<'tcx>,
-    used_trait_imports: FxHashSet<LocalDefId>,
-}
-
-impl<'tcx> CheckVisitor<'tcx> {
-    fn check_import(&self, item_id: hir::ItemId, span: Span) {
-        if !self.tcx.maybe_unused_trait_import(item_id.def_id) {
-            return;
-        }
-
-        if self.used_trait_imports.contains(&item_id.def_id) {
-            return;
-        }
+    used_trait_imports: &mut FxHashSet<LocalDefId>,
+    item_id: hir::ItemId,
+    span: Span,
+) {
+    if !tcx.maybe_unused_trait_import(item_id.def_id) {
+        return;
+    }
 
-        self.tcx.struct_span_lint_hir(
-            lint::builtin::UNUSED_IMPORTS,
-            item_id.hir_id(),
-            span,
-            |lint| {
-                let msg = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
-                    format!("unused import: `{}`", snippet)
-                } else {
-                    "unused import".to_owned()
-                };
-                lint.build(&msg).emit();
-            },
-        );
+    if used_trait_imports.contains(&item_id.def_id) {
+        return;
     }
+
+    tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item_id.hir_id(), span, |lint| {
+        let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
+            format!("unused import: `{}`", snippet)
+        } else {
+            "unused import".to_owned()
+        };
+        lint.build(&msg).emit();
+    });
 }
 
 fn unused_crates_lint(tcx: TyCtxt<'_>) {
@@ -110,9 +96,20 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
 
     // Collect all the extern crates (in a reliable order).
     let mut crates_to_lint = vec![];
-    tcx.hir().visit_all_item_likes(&mut CollectExternCrateVisitor {
-        crates_to_lint: &mut crates_to_lint,
-    });
+
+    for id in tcx.hir().items() {
+        if matches!(tcx.hir().def_kind(id.def_id), DefKind::ExternCrate) {
+            let item = tcx.hir().item(id);
+            if let hir::ItemKind::ExternCrate(orig_name) = item.kind {
+                crates_to_lint.push(ExternCrateToLint {
+                    def_id: item.def_id.to_def_id(),
+                    span: item.span,
+                    orig_name,
+                    warn_if_unused: !item.ident.as_str().starts_with('_'),
+                });
+            }
+        }
+    }
 
     let extern_prelude = &tcx.resolutions(()).extern_prelude;
 
@@ -193,10 +190,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
     }
 }
 
-struct CollectExternCrateVisitor<'a> {
-    crates_to_lint: &'a mut Vec<ExternCrateToLint>,
-}
-
 struct ExternCrateToLint {
     /// `DefId` of the extern crate
     def_id: DefId,
@@ -213,22 +206,3 @@ struct ExternCrateToLint {
     /// about it going unused (but we should still emit idiom lints).
     warn_if_unused: bool,
 }
-
-impl<'a, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        if let hir::ItemKind::ExternCrate(orig_name) = item.kind {
-            self.crates_to_lint.push(ExternCrateToLint {
-                def_id: item.def_id.to_def_id(),
-                span: item.span,
-                orig_name,
-                warn_if_unused: !item.ident.as_str().starts_with('_'),
-            });
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
-
-    fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
-}
diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
index 00163c72974..6f842c6e71a 100644
--- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs
@@ -1,7 +1,6 @@
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
@@ -29,81 +28,57 @@ pub fn infer_predicates<'tcx>(
     while predicates_added {
         predicates_added = false;
 
-        let mut visitor = InferVisitor {
-            tcx,
-            global_inferred_outlives: &mut global_inferred_outlives,
-            predicates_added: &mut predicates_added,
-            explicit_map,
-        };
-
         // Visit all the crates and infer predicates
-        tcx.hir().visit_all_item_likes(&mut visitor);
-    }
+        for id in tcx.hir().items() {
+            let item_did = id.def_id;
 
-    global_inferred_outlives
-}
+            debug!("InferVisitor::visit_item(item={:?})", item_did);
 
-pub struct InferVisitor<'cx, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
-    predicates_added: &'cx mut bool,
-    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
-}
-
-impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        let item_did = item.def_id;
-
-        debug!("InferVisitor::visit_item(item={:?})", item_did);
+            let mut item_required_predicates = RequiredPredicates::default();
+            match tcx.hir().def_kind(item_did) {
+                DefKind::Union | DefKind::Enum | DefKind::Struct => {
+                    let adt_def = tcx.adt_def(item_did.to_def_id());
 
-        let mut item_required_predicates = RequiredPredicates::default();
-        match item.kind {
-            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => {
-                let adt_def = self.tcx.adt_def(item_did.to_def_id());
-
-                // Iterate over all fields in item_did
-                for field_def in adt_def.all_fields() {
-                    // Calculating the predicate requirements necessary
-                    // for item_did.
-                    //
-                    // For field of type &'a T (reference) or Adt
-                    // (struct/enum/union) there will be outlive
-                    // requirements for adt_def.
-                    let field_ty = self.tcx.type_of(field_def.did);
-                    let field_span = self.tcx.def_span(field_def.did);
-                    insert_required_predicates_to_be_wf(
-                        self.tcx,
-                        field_ty,
-                        field_span,
-                        self.global_inferred_outlives,
-                        &mut item_required_predicates,
-                        &mut self.explicit_map,
-                    );
+                    // Iterate over all fields in item_did
+                    for field_def in adt_def.all_fields() {
+                        // Calculating the predicate requirements necessary
+                        // for item_did.
+                        //
+                        // For field of type &'a T (reference) or Adt
+                        // (struct/enum/union) there will be outlive
+                        // requirements for adt_def.
+                        let field_ty = tcx.type_of(field_def.did);
+                        let field_span = tcx.def_span(field_def.did);
+                        insert_required_predicates_to_be_wf(
+                            tcx,
+                            field_ty,
+                            field_span,
+                            &mut global_inferred_outlives,
+                            &mut item_required_predicates,
+                            explicit_map,
+                        );
+                    }
                 }
-            }
 
-            _ => {}
-        };
+                _ => {}
+            };
 
-        // If new predicates were added (`local_predicate_map` has more
-        // predicates than the `global_inferred_outlives`), the new predicates
-        // might result in implied predicates for their parent types.
-        // Therefore mark `predicates_added` as true and which will ensure
-        // we walk the crates again and re-calculate predicates for all
-        // items.
-        let item_predicates_len: usize =
-            self.global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len());
-        if item_required_predicates.len() > item_predicates_len {
-            *self.predicates_added = true;
-            self.global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates);
+            // If new predicates were added (`local_predicate_map` has more
+            // predicates than the `global_inferred_outlives`), the new predicates
+            // might result in implied predicates for their parent types.
+            // Therefore mark `predicates_added` as true and which will ensure
+            // we walk the crates again and re-calculate predicates for all
+            // items.
+            let item_predicates_len: usize =
+                global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len());
+            if item_required_predicates.len() > item_predicates_len {
+                predicates_added = true;
+                global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates);
+            }
         }
     }
 
-    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {}
-
-    fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {}
+    global_inferred_outlives
 }
 
 fn insert_required_predicates_to_be_wf<'tcx>(