From 2db2776589eced747c35e030aa185f3a4fc93ffa Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Wed, 8 Apr 2020 17:03:34 +0200
Subject: [PATCH] Wrap TyCtxt inside a QueryCtxt for queries.

---
 compiler/rustc_macros/src/query.rs            | 26 ++++----
 .../rustc_middle/src/dep_graph/dep_node.rs    |  5 +-
 compiler/rustc_middle/src/query/mod.rs        |  1 +
 compiler/rustc_middle/src/ty/query/job.rs     |  5 +-
 compiler/rustc_middle/src/ty/query/mod.rs     |  1 +
 .../src/ty/query/on_disk_cache.rs             |  7 +-
 .../rustc_middle/src/ty/query/plumbing.rs     | 65 +++++++++++++------
 compiler/rustc_middle/src/ty/query/stats.rs   |  6 +-
 compiler/rustc_middle/src/ty/query/values.rs  | 15 +++--
 9 files changed, 82 insertions(+), 49 deletions(-)

diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 48b74bdaf1e..1ac71824faf 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -354,9 +354,10 @@ fn add_query_description_impl(
             quote! {
                 #[inline]
                 fn try_load_from_disk(
-                    #tcx: TyCtxt<'tcx>,
-                    #id: SerializedDepNodeIndex
+                    tcx: QueryCtxt<'tcx>,
+                    id: SerializedDepNodeIndex
                 ) -> Option<Self::Value> {
+                    let (#tcx, #id) = (*tcx, id);
                     #block
                 }
             }
@@ -365,10 +366,10 @@ fn add_query_description_impl(
             quote! {
                 #[inline]
                 fn try_load_from_disk(
-                    tcx: TyCtxt<'tcx>,
+                    tcx: QueryCtxt<'tcx>,
                     id: SerializedDepNodeIndex
                 ) -> Option<Self::Value> {
-                    tcx.on_disk_cache.as_ref()?.try_load_query_result(tcx, id)
+                    tcx.on_disk_cache.as_ref()?.try_load_query_result(*tcx, id)
                 }
             }
         };
@@ -393,10 +394,11 @@ fn add_query_description_impl(
             #[inline]
             #[allow(unused_variables, unused_braces)]
             fn cache_on_disk(
-                #tcx: TyCtxt<'tcx>,
-                #key: &Self::Key,
-                #value: Option<&Self::Value>
+                tcx: QueryCtxt<'tcx>,
+                key: &Self::Key,
+                value: Option<&Self::Value>
             ) -> bool {
+                let (#tcx, #key, #value) = (*tcx, key, value);
                 #expr
             }
 
@@ -414,16 +416,14 @@ fn add_query_description_impl(
 
     let desc = quote! {
         #[allow(unused_variables)]
-        fn describe(
-            #tcx: TyCtxt<'tcx>,
-            #key: #arg,
-        ) -> String {
-            ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc))
+        fn describe(tcx: QueryCtxt<'tcx>, key: #arg) -> String {
+            let (#tcx, #key) = (*tcx, key);
+            ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
         }
     };
 
     impls.extend(quote! {
-        impl<'tcx> QueryDescription<TyCtxt<'tcx>> for queries::#name<'tcx> {
+        impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::#name<'tcx> {
             #desc
             #cache
         }
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 669d7ea8d36..ea1376e41c9 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -55,6 +55,7 @@
 //!
 //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
 
+use crate::ty::query::QueryCtxt;
 use crate::ty::TyCtxt;
 
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -261,7 +262,7 @@ pub mod dep_kind {
 
                     if let Some(key) = recover(tcx, dep_node) {
                         force_query::<queries::$variant<'_>, _>(
-                            tcx,
+                            QueryCtxt(tcx),
                             key,
                             DUMMY_SP,
                             *dep_node
@@ -287,7 +288,7 @@ pub mod dep_kind {
                                      .unwrap_or(false));
 
                     let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
-                    if queries::$variant::cache_on_disk(tcx, &key, None) {
+                    if queries::$variant::cache_on_disk(QueryCtxt(tcx), &key, None) {
                         let _ = tcx.$variant(key);
                     }
                 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 47b77bed906..0f7728d48d9 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -7,6 +7,7 @@ use crate::traits::query::{
     CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
 };
 use crate::ty::query::queries;
+use crate::ty::query::QueryCtxt;
 use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
diff --git a/compiler/rustc_middle/src/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs
index bd2e7747b7d..0ea8bcc9d9d 100644
--- a/compiler/rustc_middle/src/ty/query/job.rs
+++ b/compiler/rustc_middle/src/ty/query/job.rs
@@ -1,3 +1,4 @@
+use crate::ty::query::QueryCtxt;
 use crate::ty::tls;
 
 use rustc_query_system::query::deadlock;
@@ -20,7 +21,7 @@ pub unsafe fn handle_deadlock() {
     thread::spawn(move || {
         tls::enter_context(icx, |_| {
             rustc_span::SESSION_GLOBALS
-                .set(session_globals, || tls::with(|tcx| deadlock(tcx, &registry)))
-        })
+                .set(session_globals, || tls::with(|tcx| deadlock(QueryCtxt(tcx), &registry)))
+        });
     });
 }
diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs
index 804c045a690..88d1efffea7 100644
--- a/compiler/rustc_middle/src/ty/query/mod.rs
+++ b/compiler/rustc_middle/src/ty/query/mod.rs
@@ -60,6 +60,7 @@ use std::sync::Arc;
 
 #[macro_use]
 mod plumbing;
+pub use plumbing::QueryCtxt;
 pub(crate) use rustc_query_system::query::CycleError;
 use rustc_query_system::query::*;
 
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 9f9f6bc4c51..5e862afae37 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -3,6 +3,7 @@ use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use crate::mir::{self, interpret};
 use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
 use crate::ty::context::TyCtxt;
+use crate::ty::query::QueryCtxt;
 use crate::ty::{self, Ty};
 use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
@@ -312,7 +313,7 @@ impl<'sess> OnDiskCache<'sess> {
                     ($($query:ident,)*) => {
                         $(
                             encode_query_results::<ty::query::queries::$query<'_>>(
-                                tcx,
+                                QueryCtxt(tcx),
                                 enc,
                                 qri
                             )?;
@@ -1230,12 +1231,12 @@ impl<'a> Decodable<opaque::Decoder<'a>> for IntEncodedWithFixedSize {
 }
 
 fn encode_query_results<'a, 'tcx, Q>(
-    tcx: TyCtxt<'tcx>,
+    tcx: QueryCtxt<'tcx>,
     encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
     query_result_index: &mut EncodedQueryResultIndex,
 ) -> FileEncodeResult
 where
-    Q: super::QueryDescription<TyCtxt<'tcx>> + super::QueryAccessors<TyCtxt<'tcx>>,
+    Q: super::QueryDescription<QueryCtxt<'tcx>> + super::QueryAccessors<QueryCtxt<'tcx>>,
     Q::Value: Encodable<CacheEncoder<'a, 'tcx, FileEncoder>>,
 {
     let _timer = tcx
diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs
index 8eb060a39a5..91a267e38d5 100644
--- a/compiler/rustc_middle/src/ty/query/plumbing.rs
+++ b/compiler/rustc_middle/src/ty/query/plumbing.rs
@@ -5,6 +5,7 @@
 use crate::ty::query::Query;
 use crate::ty::tls::{self, ImplicitCtxt};
 use crate::ty::{self, TyCtxt};
+use rustc_query_system::dep_graph::HasDepContext;
 use rustc_query_system::query::QueryContext;
 use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo};
 
@@ -15,7 +16,29 @@ use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Leve
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 
-impl QueryContext for TyCtxt<'tcx> {
+#[derive(Copy, Clone)]
+pub struct QueryCtxt<'tcx>(pub TyCtxt<'tcx>);
+
+impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> {
+    type Target = TyCtxt<'tcx>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl HasDepContext for QueryCtxt<'tcx> {
+    type DepKind = crate::dep_graph::DepKind;
+    type StableHashingContext = crate::ich::StableHashingContext<'tcx>;
+    type DepContext = TyCtxt<'tcx>;
+
+    #[inline]
+    fn dep_context(&self) -> &Self::DepContext {
+        &self.0
+    }
+}
+
+impl QueryContext for QueryCtxt<'tcx> {
     type Query = Query<'tcx>;
 
     fn incremental_verify_ich(&self) -> bool {
@@ -26,11 +49,11 @@ impl QueryContext for TyCtxt<'tcx> {
     }
 
     fn def_path_str(&self, def_id: DefId) -> String {
-        TyCtxt::def_path_str(*self, def_id)
+        self.0.def_path_str(def_id)
     }
 
     fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>> {
-        tls::with_related_context(*self, |icx| icx.query)
+        tls::with_related_context(**self, |icx| icx.query)
     }
 
     fn try_collect_active_jobs(
@@ -53,10 +76,10 @@ impl QueryContext for TyCtxt<'tcx> {
         // The `TyCtxt` stored in TLS has the same global interner lifetime
         // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
         // when accessing the `ImplicitCtxt`.
-        tls::with_related_context(*self, move |current_icx| {
+        tls::with_related_context(**self, move |current_icx| {
             // Update the `ImplicitCtxt` to point to our new query job.
             let new_icx = ImplicitCtxt {
-                tcx: *self,
+                tcx: **self,
                 query: Some(token),
                 diagnostics,
                 layout_depth: current_icx.layout_depth,
@@ -71,7 +94,7 @@ impl QueryContext for TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'tcx> QueryCtxt<'tcx> {
     #[inline(never)]
     #[cold]
     pub(super) fn report_cycle(
@@ -81,7 +104,7 @@ impl<'tcx> TyCtxt<'tcx> {
         assert!(!stack.is_empty());
 
         let fix_span = |span: Span, query: &Query<'tcx>| {
-            self.sess.source_map().guess_head_span(query.default_span(self, span))
+            self.sess.source_map().guess_head_span(query.default_span(*self, span))
         };
 
         // Disable naming impls with types in this path, since that
@@ -119,7 +142,9 @@ impl<'tcx> TyCtxt<'tcx> {
             err
         })
     }
+}
 
+impl<'tcx> TyCtxt<'tcx> {
     pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
         eprintln!("query stack during panic:");
 
@@ -149,7 +174,7 @@ impl<'tcx> TyCtxt<'tcx> {
                             "#{} [{}] {}",
                             i,
                             query_info.info.query.name(),
-                            query_info.info.query.describe(icx.tcx)
+                            query_info.info.query.describe(QueryCtxt(icx.tcx))
                         ),
                     );
                     diag.span =
@@ -272,7 +297,7 @@ macro_rules! define_queries {
                 }
             }
 
-            pub fn describe(&self, tcx: TyCtxt<$tcx>) -> String {
+            pub(crate) fn describe(&self, tcx: QueryCtxt<$tcx>) -> String {
                 let (r, name) = match *self {
                     $(Query::$name(key) => {
                         (queries::$name::describe(tcx, key), stringify!($name))
@@ -362,7 +387,7 @@ macro_rules! define_queries {
             const NAME: &'static str = stringify!($name);
         }
 
-        impl<$tcx> QueryAccessors<TyCtxt<$tcx>> for queries::$name<$tcx> {
+        impl<$tcx> QueryAccessors<QueryCtxt<$tcx>> for queries::$name<$tcx> {
             const ANON: bool = is_anon!([$($modifiers)*]);
             const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
             const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$name;
@@ -370,19 +395,19 @@ macro_rules! define_queries {
             type Cache = query_storage::$name<$tcx>;
 
             #[inline(always)]
-            fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<crate::dep_graph::DepKind, Query<$tcx>, Self::Key> {
+            fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<crate::dep_graph::DepKind, Query<$tcx>, Self::Key> {
                 &tcx.queries.$name
             }
 
             #[inline(always)]
-            fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryCacheStore<Self::Cache>
+            fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryCacheStore<Self::Cache>
                 where 'tcx:'a
             {
                 &tcx.query_caches.$name
             }
 
             #[inline]
-            fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
+            fn compute(tcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
                 let provider = tcx.queries.providers.get(key.query_crate())
                     // HACK(eddyb) it's possible crates may be loaded after
                     // the query engine is created, and because crate loading
@@ -390,7 +415,7 @@ macro_rules! define_queries {
                     // would be missing appropriate entries in `providers`.
                     .unwrap_or(&tcx.queries.fallback_extern_providers)
                     .$name;
-                provider(tcx, key)
+                provider(*tcx, key)
             }
 
             fn hash_result(
@@ -401,7 +426,7 @@ macro_rules! define_queries {
             }
 
             fn handle_cycle_error(
-                tcx: TyCtxt<'tcx>,
+                tcx: QueryCtxt<'tcx>,
                 error: CycleError<Query<'tcx>>
             ) -> Self::Value {
                 handle_cycle_error!([$($modifiers)*][tcx, error])
@@ -425,7 +450,8 @@ macro_rules! define_queries {
                     Err(lookup) => lookup,
                 };
 
-                get_query::<queries::$name<'_>, _>(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
+                let qcx = QueryCtxt(self.tcx);
+                get_query::<queries::$name<'_>, _>(qcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
             })*
         }
 
@@ -516,7 +542,8 @@ macro_rules! define_queries {
                     Err(lookup) => lookup,
                 };
 
-                get_query::<queries::$name<'_>, _>(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
+                let qcx = QueryCtxt(self.tcx);
+                get_query::<queries::$name<'_>, _>(qcx, self.span, key, lookup, QueryMode::Get).unwrap()
             })*
         }
 
@@ -558,12 +585,12 @@ macro_rules! define_queries_struct {
 
             pub(crate) fn try_collect_active_jobs(
                 &self
-            ) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, <TyCtxt<$tcx> as QueryContext>::Query>>> {
+            ) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, Query<$tcx>>>> {
                 let mut jobs = FxHashMap::default();
 
                 $(
                     self.$name.try_collect_active_jobs(
-                        <queries::$name<'tcx> as QueryAccessors<TyCtxt<'tcx>>>::DEP_KIND,
+                        <queries::$name<'tcx> as QueryAccessors<QueryCtxt<'tcx>>>::DEP_KIND,
                         Query::$name,
                         &mut jobs,
                     )?;
diff --git a/compiler/rustc_middle/src/ty/query/stats.rs b/compiler/rustc_middle/src/ty/query/stats.rs
index 29ec9c132a8..47cbc7e43d2 100644
--- a/compiler/rustc_middle/src/ty/query/stats.rs
+++ b/compiler/rustc_middle/src/ty/query/stats.rs
@@ -1,7 +1,7 @@
-use crate::ty::query::queries;
+use crate::ty::query::query_storage;
 use crate::ty::TyCtxt;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_query_system::query::{QueryAccessors, QueryCache, QueryCacheStore};
+use rustc_query_system::query::{QueryCache, QueryCacheStore};
 
 use std::any::type_name;
 use std::mem;
@@ -125,7 +125,7 @@ macro_rules! print_stats {
 
             $(
                 queries.push(stats::<
-                    <queries::$name<'_> as QueryAccessors<TyCtxt<'_>>>::Cache,
+                    query_storage::$name<'_>,
                 >(
                     stringify!($name),
                     &tcx.query_caches.$name,
diff --git a/compiler/rustc_middle/src/ty/query/values.rs b/compiler/rustc_middle/src/ty/query/values.rs
index f28b0f499f0..fa15395db4e 100644
--- a/compiler/rustc_middle/src/ty/query/values.rs
+++ b/compiler/rustc_middle/src/ty/query/values.rs
@@ -1,18 +1,19 @@
-use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt, TyS};
+use crate::ty::query::QueryCtxt;
+use crate::ty::{self, AdtSizedConstraint, Ty, TyS};
 
 pub(super) trait Value<'tcx>: Sized {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self;
+    fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
 }
 
 impl<'tcx, T> Value<'tcx> for T {
-    default fn from_cycle_error(tcx: TyCtxt<'tcx>) -> T {
+    default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
         tcx.sess.abort_if_errors();
         bug!("Value::from_cycle_error called without errors");
     }
 }
 
 impl<'tcx> Value<'tcx> for &'_ TyS<'_> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+    fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
         // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
         // FIXME: Represent the above fact in the trait system somehow.
         unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
@@ -20,19 +21,19 @@ impl<'tcx> Value<'tcx> for &'_ TyS<'_> {
 }
 
 impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+    fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
         // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
         // FIXME: Represent the above fact in the trait system somehow.
         unsafe {
             std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
-                tcx, "<error>",
+                *tcx, "<error>",
             ))
         }
     }
 }
 
 impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
+    fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
         // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
         // FIXME: Represent the above fact in the trait system somehow.
         unsafe {