diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 0a74e2b8522..30a367052cb 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -23,7 +23,7 @@ use tracing::debug;
 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
 /// stores the `DefIndex` of its parent.
 /// There is one `DefPathTable` for each crate.
-#[derive(Clone, Default)]
+#[derive(Clone, Default, Debug)]
 pub struct DefPathTable {
     index_to_key: IndexVec<DefIndex, DefKey>,
     def_path_hashes: IndexVec<DefIndex, DefPathHash>,
@@ -96,7 +96,7 @@ impl DefPathTable {
 /// The definition table containing node definitions.
 /// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
 /// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct Definitions {
     table: DefPathTable,
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 557a36b2183..250af3c6e89 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -51,6 +51,12 @@ pub struct CStore {
     unused_externs: Vec<Symbol>,
 }
 
+impl std::fmt::Debug for CStore {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("CStore").finish_non_exhaustive()
+    }
+}
+
 pub struct CrateLoader<'a> {
     // Immutable configuration.
     sess: &'a Session,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 07b39c97c49..c901f101d94 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -156,11 +156,13 @@ impl<'hir> Map<'hir> {
 
     #[inline]
     pub fn definitions(&self) -> &'hir Definitions {
-        &self.tcx.definitions
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        &self.tcx.untracked_resolutions.definitions
     }
 
     pub fn def_key(&self, def_id: LocalDefId) -> DefKey {
-        self.tcx.definitions.def_key(def_id)
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        self.tcx.untracked_resolutions.definitions.def_key(def_id)
     }
 
     pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
@@ -168,7 +170,8 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn def_path(&self, def_id: LocalDefId) -> DefPath {
-        self.tcx.definitions.def_path(def_id)
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        self.tcx.untracked_resolutions.definitions.def_path(def_id)
     }
 
     #[inline]
@@ -184,16 +187,19 @@ impl<'hir> Map<'hir> {
 
     #[inline]
     pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<LocalDefId> {
-        self.tcx.definitions.opt_hir_id_to_local_def_id(hir_id)
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        self.tcx.untracked_resolutions.definitions.opt_hir_id_to_local_def_id(hir_id)
     }
 
     #[inline]
     pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
-        self.tcx.definitions.local_def_id_to_hir_id(def_id)
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        self.tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id)
     }
 
     pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
-        self.tcx.definitions.iter_local_def_id()
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        self.tcx.untracked_resolutions.definitions.iter_local_def_id()
     }
 
     pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
@@ -932,9 +938,15 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
 pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
     let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
 
+    // We can access untracked state since we are an eval_always query.
     let hcx = tcx.create_stable_hashing_context();
-    let mut collector =
-        NodeCollector::root(tcx.sess, &**tcx.arena, tcx.untracked_crate, &tcx.definitions, hcx);
+    let mut collector = NodeCollector::root(
+        tcx.sess,
+        &**tcx.arena,
+        tcx.untracked_crate,
+        &tcx.untracked_resolutions.definitions,
+        hcx,
+    );
     intravisit::walk_crate(&mut collector, tcx.untracked_crate);
 
     let map = collector.finalize_and_compute_crate_hash();
@@ -944,6 +956,7 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tc
 pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
     assert_eq!(crate_num, LOCAL_CRATE);
 
+    // We can access untracked state since we are an eval_always query.
     let mut hcx = tcx.create_stable_hashing_context();
 
     let mut hir_body_nodes: Vec<_> = tcx
@@ -951,7 +964,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
         .map
         .iter_enumerated()
         .filter_map(|(def_id, hod)| {
-            let def_path_hash = tcx.definitions.def_path_hash(def_id);
+            let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
             let mut hasher = StableHasher::new();
             hod.as_ref()?.hash_stable(&mut hcx, &mut hasher);
             AttributeMap { map: &tcx.untracked_crate.attrs, prefix: def_id }
@@ -968,7 +981,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
         },
     );
 
-    let upstream_crates = upstream_crates(&*tcx.cstore);
+    let upstream_crates = upstream_crates(&*tcx.untracked_resolutions.cstore);
 
     // We hash the final, remapped names of all local source files so we
     // don't have to include the path prefix remapping commandline args.
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 087f772c812..3026bf8274d 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -169,6 +169,6 @@ pub fn provide(providers: &mut Providers) {
     providers.all_local_trait_impls = |tcx, ()| &tcx.hir_crate(()).trait_impls;
     providers.expn_that_defined = |tcx, id| {
         let id = id.expect_local();
-        tcx.definitions.expansion_that_defined(id)
+        tcx.resolutions(()).definitions.expansion_that_defined(id)
     };
 }
diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs
index fccf1569e61..c46f6c8c955 100644
--- a/compiler/rustc_middle/src/middle/cstore.rs
+++ b/compiler/rustc_middle/src/middle/cstore.rs
@@ -168,7 +168,7 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
 /// that it's *not* tracked for dependency information throughout compilation
 /// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
 /// during resolve)
-pub trait CrateStore {
+pub trait CrateStore: std::fmt::Debug {
     fn as_any(&self) -> &dyn Any;
 
     // resolve
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index c4b990faed0..d0438ed8ef4 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -14,6 +14,12 @@ rustc_queries! {
         desc { "trigger a delay span bug" }
     }
 
+    query resolutions(_: ()) -> &'tcx ty::ResolverOutputs {
+        eval_always
+        no_hash
+        desc { "get the resolver outputs" }
+    }
+
     /// Represents crate as a whole (as distinct from the top-level crate module).
     /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
     /// we will have to assume that any change means that you need to be recompiled.
@@ -207,7 +213,6 @@ rustc_queries! {
     }
 
     query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
-        eval_always
         desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
     }
 
@@ -1129,7 +1134,6 @@ rustc_queries! {
 
     query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export<LocalDefId>]> {
         desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
-        eval_always
     }
 
     query impl_defaultness(def_id: DefId) -> hir::Defaultness {
@@ -1319,7 +1323,6 @@ rustc_queries! {
     }
 
     query visibility(def_id: DefId) -> ty::Visibility {
-        eval_always
         desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
     }
 
@@ -1344,8 +1347,6 @@ rustc_queries! {
         desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
     }
     query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
-        // This depends on untracked global state (`tcx.extern_crate_map`)
-        eval_always
         desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
     }
 
@@ -1422,16 +1423,12 @@ rustc_queries! {
         eval_always
     }
     query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
-        eval_always
         desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
     }
     query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
-        eval_always
         desc { "looking up all possibly unused extern crates" }
     }
-    query names_imported_by_glob_use(def_id: LocalDefId)
-        -> &'tcx FxHashSet<Symbol> {
-        eval_always
+    query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet<Symbol> {
         desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
     }
 
@@ -1441,7 +1438,6 @@ rustc_queries! {
         desc { "calculating the stability index for the local crate" }
     }
     query crates(_: ()) -> &'tcx [CrateNum] {
-        eval_always
         desc { "fetching all foreign CrateNum instances" }
     }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 9c98592c865..25fd02bc29c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2,13 +2,12 @@
 
 use crate::arena::Arena;
 use crate::dep_graph::DepGraph;
-use crate::hir::exports::ExportMap;
 use crate::hir::place::Place as HirPlace;
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
 use crate::middle;
-use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
+use crate::middle::cstore::EncodedMetadata;
 use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
 use crate::middle::stability;
 use crate::mir::interpret::{self, AllocId, Allocation, ConstValue, Scalar};
@@ -21,10 +20,9 @@ use crate::ty::TyKind::*;
 use crate::ty::{
     self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
     ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
-    FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
-    MainDefinition, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
-    ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
-    TyVid, TypeAndMut, UintTy, Visibility,
+    FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
+    ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
+    ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
 };
 use rustc_ast as ast;
 use rustc_attr as attr;
@@ -39,7 +37,6 @@ use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
-use rustc_hir::definitions::Definitions;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
@@ -966,8 +963,6 @@ pub struct GlobalCtxt<'tcx> {
 
     interners: CtxtInterners<'tcx>,
 
-    pub(crate) cstore: Box<CrateStoreDyn>,
-
     pub sess: &'tcx Session,
 
     /// This only ever stores a `LintStore` but we don't want a dependency on that type here.
@@ -989,17 +984,10 @@ pub struct GlobalCtxt<'tcx> {
     /// Common consts, pre-interned for your convenience.
     pub consts: CommonConsts<'tcx>,
 
-    /// Visibilities produced by resolver.
-    pub visibilities: FxHashMap<LocalDefId, Visibility>,
-
-    /// Resolutions of `extern crate` items produced by resolver.
-    extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-
-    /// Export map produced by name resolution.
-    export_map: ExportMap<LocalDefId>,
+    /// Output of the resolver.
+    pub(crate) untracked_resolutions: ty::ResolverOutputs,
 
     pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
-    pub(crate) definitions: Definitions,
 
     /// This provides access to the incremental compilation on-disk cache for query results.
     /// Do not access this directly. It is only meant to be used by
@@ -1010,15 +998,6 @@ pub struct GlobalCtxt<'tcx> {
     pub queries: &'tcx dyn query::QueryEngine<'tcx>,
     pub query_caches: query::QueryCaches<'tcx>,
 
-    maybe_unused_trait_imports: FxHashSet<LocalDefId>,
-    maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
-    /// A map of glob use to a set of names it actually imports. Currently only
-    /// used in save-analysis.
-    pub(crate) glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
-    /// Extern prelude entries. The value is `true` if the entry was introduced
-    /// via `extern crate` item and not `--extern` option or compiler built-in.
-    pub extern_prelude: FxHashMap<Symbol, bool>,
-
     // Internal caches for metadata decoding. No need to track deps on this.
     pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
     pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
@@ -1052,8 +1031,6 @@ pub struct GlobalCtxt<'tcx> {
 
     output_filenames: Arc<OutputFilenames>,
 
-    pub main_def: Option<MainDefinition>,
-
     pub(super) vtables_cache:
         Lock<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>>,
 }
@@ -1176,28 +1153,19 @@ impl<'tcx> TyCtxt<'tcx> {
         let common_types = CommonTypes::new(&interners);
         let common_lifetimes = CommonLifetimes::new(&interners);
         let common_consts = CommonConsts::new(&interners, &common_types);
-        let cstore = resolutions.cstore;
 
         GlobalCtxt {
             sess: s,
             lint_store,
-            cstore,
             arena,
             interners,
             dep_graph,
+            untracked_resolutions: resolutions,
             prof: s.prof.clone(),
             types: common_types,
             lifetimes: common_lifetimes,
             consts: common_consts,
-            visibilities: resolutions.visibilities,
-            extern_crate_map: resolutions.extern_crate_map,
-            export_map: resolutions.export_map,
-            maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
-            maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates,
-            glob_map: resolutions.glob_map,
-            extern_prelude: resolutions.extern_prelude,
             untracked_crate: krate,
-            definitions: resolutions.definitions,
             on_disk_cache,
             queries,
             query_caches: query::QueryCaches::default(),
@@ -1212,7 +1180,6 @@ impl<'tcx> TyCtxt<'tcx> {
             const_stability_interner: Default::default(),
             alloc_map: Lock::new(interpret::AllocMap::new()),
             output_filenames: Arc::new(output_filenames),
-            main_def: resolutions.main_def,
             vtables_cache: Default::default(),
         }
     }
@@ -1273,7 +1240,12 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
-        if let Some(id) = id.as_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) }
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
+        if let Some(id) = id.as_local() {
+            self.hir().def_key(id)
+        } else {
+            self.untracked_resolutions.cstore.def_key(id)
+        }
     }
 
     /// Converts a `DefId` into its fully expanded `DefPath` (every
@@ -1282,19 +1254,21 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Note that if `id` is not local to this crate, the result will
     ///  be a non-local `DefPath`.
     pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
         if let Some(id) = id.as_local() {
             self.hir().def_path(id)
         } else {
-            self.cstore.def_path(id)
+            self.untracked_resolutions.cstore.def_path(id)
         }
     }
 
     #[inline]
     pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
+        // Accessing the definitions is ok, since all its contents are tracked by the query system.
         if let Some(def_id) = def_id.as_local() {
-            self.definitions.def_path_hash(def_id)
+            self.untracked_resolutions.definitions.def_path_hash(def_id)
         } else {
-            self.cstore.def_path_hash(def_id)
+            self.untracked_resolutions.cstore.def_path_hash(def_id)
         }
     }
 
@@ -1303,7 +1277,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if crate_num == LOCAL_CRATE {
             self.sess.local_stable_crate_id()
         } else {
-            self.cstore.stable_crate_id_untracked(crate_num)
+            self.untracked_resolutions.cstore.stable_crate_id_untracked(crate_num)
         }
     }
 
@@ -1315,9 +1289,10 @@ impl<'tcx> TyCtxt<'tcx> {
         let (crate_name, stable_crate_id) = if def_id.is_local() {
             (self.crate_name, self.sess.local_stable_crate_id())
         } else {
+            let cstore = &self.untracked_resolutions.cstore;
             (
-                self.cstore.crate_name_untracked(def_id.krate),
-                self.def_path_hash(def_id.krate.as_def_id()).stable_crate_id(),
+                cstore.crate_name_untracked(def_id.krate),
+                cstore.stable_crate_id_untracked(def_id.krate),
             )
         };
 
@@ -1333,27 +1308,34 @@ impl<'tcx> TyCtxt<'tcx> {
 
     pub fn encode_metadata(self) -> EncodedMetadata {
         let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
-        self.cstore.encode_metadata(self)
+        self.untracked_resolutions.cstore.encode_metadata(self)
     }
 
     // Note that this is *untracked* and should only be used within the query
     // system if the result is otherwise tracked through queries
     pub fn cstore_as_any(self) -> &'tcx dyn Any {
-        self.cstore.as_any()
+        self.untracked_resolutions.cstore.as_any()
     }
 
     #[inline(always)]
     pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
         let krate = self.gcx.untracked_crate;
+        let resolutions = &self.gcx.untracked_resolutions;
 
-        StableHashingContext::new(self.sess, krate, &self.definitions, &*self.cstore)
+        StableHashingContext::new(self.sess, krate, &resolutions.definitions, &*resolutions.cstore)
     }
 
     #[inline(always)]
     pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
         let krate = self.gcx.untracked_crate;
+        let resolutions = &self.gcx.untracked_resolutions;
 
-        StableHashingContext::ignore_spans(self.sess, krate, &self.definitions, &*self.cstore)
+        StableHashingContext::ignore_spans(
+            self.sess,
+            krate,
+            &resolutions.definitions,
+            &*resolutions.cstore,
+        )
     }
 
     pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
@@ -2821,15 +2803,19 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
 
 pub fn provide(providers: &mut ty::query::Providers) {
     providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id);
-    providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
+    providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
+    providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
     providers.crate_name = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
         tcx.crate_name
     };
-    providers.maybe_unused_trait_import = |tcx, id| tcx.maybe_unused_trait_imports.contains(&id);
-    providers.maybe_unused_extern_crates = |tcx, ()| &tcx.maybe_unused_extern_crates[..];
-    providers.names_imported_by_glob_use =
-        |tcx, id| tcx.arena.alloc(tcx.glob_map.get(&id).cloned().unwrap_or_default());
+    providers.maybe_unused_trait_import =
+        |tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
+    providers.maybe_unused_extern_crates =
+        |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
+    providers.names_imported_by_glob_use = |tcx, id| {
+        tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
+    };
 
     providers.lookup_stability = |tcx, id| {
         let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
@@ -2843,8 +2829,10 @@ pub fn provide(providers: &mut ty::query::Providers) {
         let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
         tcx.stability().local_deprecation_entry(id)
     };
-    providers.extern_mod_stmt_cnum = |tcx, id| tcx.extern_crate_map.get(&id).cloned();
-    providers.crates = |tcx, ()| tcx.arena.alloc_slice(&tcx.cstore.crates_untracked());
+    providers.extern_mod_stmt_cnum =
+        |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
+    providers.crates =
+        |tcx, ()| tcx.arena.alloc_slice(&tcx.resolutions(()).cstore.crates_untracked());
     providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
     providers.features_query = |tcx, ()| tcx.sess.features_untracked();
     providers.is_panic_runtime = |tcx, cnum| {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 156e860e1a3..42a8f1763f1 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -113,6 +113,7 @@ mod sty;
 
 // Data types
 
+#[derive(Debug)]
 pub struct ResolverOutputs {
     pub definitions: rustc_hir::definitions::Definitions,
     pub cstore: Box<CrateStoreDyn>,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index cb326996111..21d5baced76 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2313,7 +2313,7 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
     let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option<DefId>> =
         &mut FxHashMap::default();
 
-    for symbol_set in tcx.glob_map.values() {
+    for symbol_set in tcx.resolutions(()).glob_map.values() {
         for symbol in symbol_set {
             unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None);
             unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None);
diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index 2bdb1ccac59..15188643d66 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -584,7 +584,9 @@ impl<'sess> OnDiskCache<'sess> {
                 debug!("def_path_hash_to_def_id({:?})", hash);
                 // Check if the `DefPathHash` corresponds to a definition in the current
                 // crate
-                if let Some(def_id) = tcx.definitions.local_def_path_hash_to_def_id(hash) {
+                if let Some(def_id) =
+                    tcx.untracked_resolutions.definitions.local_def_path_hash_to_def_id(hash)
+                {
                     let def_id = def_id.to_def_id();
                     e.insert(Some(def_id));
                     return Some(def_id);
@@ -612,7 +614,11 @@ impl<'sess> OnDiskCache<'sess> {
                 debug_assert_ne!(krate, LOCAL_CRATE);
                 // Try to find a definition in the current session, using the previous `DefIndex`
                 // as an initial guess.
-                let opt_def_id = tcx.cstore.def_path_hash_to_def_id(krate, raw_def_id.index, hash);
+                let opt_def_id = tcx.untracked_resolutions.cstore.def_path_hash_to_def_id(
+                    krate,
+                    raw_def_id.index,
+                    hash,
+                );
                 debug!("def_path_to_def_id({:?}): opt_def_id = {:?}", hash, opt_def_id);
                 e.insert(opt_def_id);
                 opt_def_id
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 34ea5e9abd4..550f4f148fd 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -147,33 +147,36 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
         Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Start))
     } else if let Some((hir_id, _)) = visitor.attr_main_fn {
         Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Main))
-    } else if let Some(def_id) = tcx.main_def.and_then(|main_def| main_def.opt_fn_def_id()) {
-        // non-local main imports are handled below
-        if def_id.is_local() {
-            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
-            if matches!(tcx.hir().find(hir_id), Some(Node::ForeignItem(_))) {
-                tcx.sess
-                    .struct_span_err(
-                        tcx.hir().span(hir_id),
-                        "the `main` function cannot be declared in an `extern` block",
+    } else {
+        if let Some(main_def) = tcx.resolutions(()).main_def {
+            if let Some(def_id) = main_def.opt_fn_def_id() {
+                // non-local main imports are handled below
+                if def_id.is_local() {
+                    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+                    if matches!(tcx.hir().find(hir_id), Some(Node::ForeignItem(_))) {
+                        tcx.sess
+                            .struct_span_err(
+                                tcx.hir().span(hir_id),
+                                "the `main` function cannot be declared in an `extern` block",
+                            )
+                            .emit();
+                        return None;
+                    }
+                }
+
+                if main_def.is_import && !tcx.features().imported_main {
+                    let span = main_def.span;
+                    feature_err(
+                        &tcx.sess.parse_sess,
+                        sym::imported_main,
+                        span,
+                        "using an imported function as entry point `main` is experimental",
                     )
                     .emit();
-                return None;
+                }
+                return Some((def_id, EntryFnType::Main));
             }
         }
-
-        if tcx.main_def.unwrap().is_import && !tcx.features().imported_main {
-            let span = tcx.main_def.unwrap().span;
-            feature_err(
-                &tcx.sess.parse_sess,
-                sym::imported_main,
-                span,
-                "using an imported function as entry point `main` is experimental",
-            )
-            .emit();
-        }
-        Some((def_id, EntryFnType::Main))
-    } else {
         no_main_err(tcx, visitor);
         None
     }
@@ -223,7 +226,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
         err.note(&note);
     }
 
-    if let Some(main_def) = tcx.main_def {
+    if let Some(main_def) = tcx.resolutions(()).main_def {
         if main_def.opt_fn_def_id().is_none() {
             // There is something at `crate::main`, but it is not a function definition.
             err.span_label(main_def.span, &format!("non-function item at `crate::main` is found"));
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 5a79a9cc6ec..d969f50c1d9 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -2031,7 +2031,7 @@ pub fn provide(providers: &mut Providers) {
 
 fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
     let def_id = def_id.expect_local();
-    match tcx.visibilities.get(&def_id) {
+    match tcx.resolutions(()).visibilities.get(&def_id) {
         Some(vis) => *vis,
         None => {
             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 836bed2a156..7e5cc771b31 100644
--- a/compiler/rustc_typeck/src/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
@@ -116,6 +116,8 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
         crates_to_lint: &mut crates_to_lint,
     });
 
+    let extern_prelude = &tcx.resolutions(()).extern_prelude;
+
     for extern_crate in &crates_to_lint {
         let def_id = extern_crate.def_id.expect_local();
         let id = tcx.hir().local_def_id_to_hir_id(def_id);
@@ -155,7 +157,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
         // If the extern crate isn't in the extern prelude,
         // there is no way it can be written as an `use`.
         let orig_name = extern_crate.orig_name.unwrap_or(item.ident.name);
-        if !tcx.extern_prelude.get(&orig_name).map_or(false, |from_item| !from_item) {
+        if !extern_prelude.get(&orig_name).map_or(false, |from_item| !from_item) {
             continue;
         }