about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2021-12-06 19:47:54 +0800
committerDeadbeef <ent3rm4n@gmail.com>2021-12-12 12:35:00 +0800
commit42963f4d50dcd077493c77d370cff07e2475a151 (patch)
tree1fc1e15eb738d335b1185561928a2b7ce6b613fb
parent8cd168f6a6aa1b848ebb54492db0eb57d72fed2f (diff)
downloadrust-42963f4d50dcd077493c77d370cff07e2475a151.tar.gz
rust-42963f4d50dcd077493c77d370cff07e2475a151.zip
Query modifier
-rw-r--r--compiler/rustc_macros/src/query.rs20
-rw-r--r--compiler/rustc_middle/src/query/mod.rs20
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/query.rs14
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs12
5 files changed, 72 insertions, 0 deletions
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 6dbba274360..478159147ac 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -58,6 +58,9 @@ enum QueryModifier {
 
     /// Use a separate query provider for local and extern crates
     SeparateProvideExtern(Ident),
+
+    /// Always remap the ParamEnv's constness before hashing and passing to the query provider
+    RemapEnvConstness(Ident),
 }
 
 impl Parse for QueryModifier {
@@ -123,6 +126,8 @@ impl Parse for QueryModifier {
             Ok(QueryModifier::EvalAlways(modifier))
         } else if modifier == "separate_provide_extern" {
             Ok(QueryModifier::SeparateProvideExtern(modifier))
+        } else if modifier == "remap_env_constness" {
+            Ok(QueryModifier::RemapEnvConstness(modifier))
         } else {
             Err(Error::new(modifier.span(), "unknown query modifier"))
         }
@@ -222,6 +227,9 @@ struct QueryModifiers {
 
     /// Use a separate query provider for local and extern crates
     separate_provide_extern: Option<Ident>,
+
+    /// Always remap the ParamEnv's constness before hashing.
+    remap_env_constness: Option<Ident>,
 }
 
 /// Process query modifiers into a struct, erroring on duplicates
@@ -236,6 +244,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
     let mut anon = None;
     let mut eval_always = None;
     let mut separate_provide_extern = None;
+    let mut remap_env_constness = None;
     for modifier in query.modifiers.0.drain(..) {
         match modifier {
             QueryModifier::LoadCached(tcx, id, block) => {
@@ -335,6 +344,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
                 }
                 separate_provide_extern = Some(ident);
             }
+            QueryModifier::RemapEnvConstness(ident) => {
+                if remap_env_constness.is_some() {
+                    panic!("duplicate modifier `remap_env_constness` for query `{}`", query.name);
+                }
+                remap_env_constness = Some(ident)
+            }
         }
     }
     let desc = desc.unwrap_or_else(|| {
@@ -351,6 +366,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
         anon,
         eval_always,
         separate_provide_extern,
+        remap_env_constness,
     }
 }
 
@@ -485,6 +501,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
         if let Some(separate_provide_extern) = &modifiers.separate_provide_extern {
             attributes.push(quote! { (#separate_provide_extern) });
         }
+        // Pass on the remap_env_constness modifier
+        if let Some(remap_env_constness) = &modifiers.remap_env_constness {
+            attributes.push(quote! { (#remap_env_constness) });
+        }
 
         // This uses the span of the query definition for the commas,
         // which can be important if we later encounter any ambiguity
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 8667a6bea11..61cbb79602c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -880,6 +880,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, ConstAlloc<'tcx>>
     ) -> Option<ty::ValTree<'tcx>> {
         desc { "destructure constant" }
+        remap_env_constness
     }
 
     /// Destructure a constant ADT or array into its variant index and its
@@ -888,6 +889,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
     ) -> mir::DestructuredConst<'tcx> {
         desc { "destructure constant" }
+        remap_env_constness
     }
 
     /// Dereference a constant reference or raw pointer and turn the result into a constant
@@ -896,6 +898,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
     ) -> &'tcx ty::Const<'tcx> {
         desc { "deref constant" }
+        remap_env_constness
     }
 
     query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
@@ -1100,26 +1103,32 @@ rustc_queries! {
     /// `ty.is_copy()`, etc, since that will prune the environment where possible.
     query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Copy`", env.value }
+        remap_env_constness
     }
     /// Query backing `TyS::is_sized`.
     query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Sized`", env.value }
+        remap_env_constness
     }
     /// Query backing `TyS::is_freeze`.
     query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is freeze", env.value }
+        remap_env_constness
     }
     /// Query backing `TyS::is_unpin`.
     query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Unpin`", env.value }
+        remap_env_constness
     }
     /// Query backing `TyS::needs_drop`.
     query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` needs drop", env.value }
+        remap_env_constness
     }
     /// Query backing `TyS::has_significant_drop_raw`.
     query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` has a significant drop", env.value }
+        remap_env_constness
     }
 
     /// Query backing `TyS::is_structural_eq_shallow`.
@@ -1158,6 +1167,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
     ) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> {
         desc { "computing layout of `{}`", key.value }
+        remap_env_constness
     }
 
     /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
@@ -1168,6 +1178,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
         desc { "computing call ABI of `{}` function pointers", key.value.0 }
+        remap_env_constness
     }
 
     /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
@@ -1179,6 +1190,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
         desc { "computing call ABI of `{}`", key.value.0 }
+        remap_env_constness
     }
 
     query dylib_dependency_formats(_: CrateNum)
@@ -1463,6 +1475,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
     ) -> ty::inhabitedness::DefIdForest {
         desc { "computing the inhabitedness of `{:?}`", key }
+        remap_env_constness
     }
 
     query dep_kind(_: CrateNum) -> CrateDepKind {
@@ -1654,6 +1667,7 @@ rustc_queries! {
         goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
     ) -> GenericArg<'tcx> {
         desc { "normalizing `{}`", goal.value }
+        remap_env_constness
     }
 
     /// Do not call this query directly: invoke `normalize_erasing_regions` instead.
@@ -1661,6 +1675,7 @@ rustc_queries! {
         goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> mir::ConstantKind<'tcx> {
         desc { "normalizing `{}`", goal.value }
+        remap_env_constness
     }
 
     /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
@@ -1668,6 +1683,7 @@ rustc_queries! {
         goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
     ) -> Result<GenericArg<'tcx>, NoSolution> {
         desc { "normalizing `{}`", goal.value }
+        remap_env_constness
     }
 
     /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
@@ -1675,6 +1691,7 @@ rustc_queries! {
         goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> Result<mir::ConstantKind<'tcx>, NoSolution> {
         desc { "normalizing `{}`", goal.value }
+        remap_env_constness
     }
 
     query implied_outlives_bounds(
@@ -1836,6 +1853,7 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>
     ) -> Result<Option<ty::Instance<'tcx>>, ErrorReported> {
         desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
+        remap_env_constness
     }
 
     query resolve_instance_of_const_arg(
@@ -1845,6 +1863,7 @@ rustc_queries! {
             "resolving instance of the const argument `{}`",
             ty::Instance::new(key.value.0.to_def_id(), key.value.2),
         }
+        remap_env_constness
     }
 
     query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
@@ -1859,6 +1878,7 @@ rustc_queries! {
     /// size, to account for partial initialisation. See #49298 for details.)
     query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "conservatively checking if {:?} is privately uninhabited", key }
+        remap_env_constness
     }
 
     query limits(key: ()) -> Limits {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 8d277240e61..a6d083101a0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1435,6 +1435,12 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> {
     pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
         (self.param_env, self.value)
     }
+
+    #[inline]
+    pub fn without_const(mut self) -> Self {
+        self.param_env = self.param_env.without_const();
+        self
+    }
 }
 
 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T>
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 34f80627197..f18517eee04 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -156,6 +156,16 @@ macro_rules! separate_provide_extern_default {
     };
 }
 
+macro_rules! opt_remap_env_constness {
+    ([][$name:ident]) => {};
+    ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
+        let $name = $name.without_const();
+    };
+    ([$other:tt $($modifiers:tt)*][$name:ident]) => {
+        opt_remap_env_constness!([$($modifiers)*][$name])
+    };
+}
+
 macro_rules! define_callbacks {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -202,6 +212,8 @@ macro_rules! define_callbacks {
             #[inline(always)]
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
                 let key = key.into_query_param();
+                opt_remap_env_constness!([$($modifiers)*][key]);
+
                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
 
                 let lookup = match cached {
@@ -229,6 +241,8 @@ macro_rules! define_callbacks {
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
             {
                 let key = key.into_query_param();
+                opt_remap_env_constness!([$($modifiers)*][key]);
+
                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, Clone::clone);
 
                 let lookup = match cached {
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 81a36e0d59e..2854ba5158b 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -231,6 +231,16 @@ macro_rules! get_provider {
     };
 }
 
+macro_rules! opt_remap_env_constness {
+    ([][$name:ident]) => {};
+    ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
+        let $name = $name.without_const();
+    };
+    ([$other:tt $($modifiers:tt)*][$name:ident]) => {
+        opt_remap_env_constness!([$($modifiers)*][$name])
+    };
+}
+
 macro_rules! define_queries {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -247,6 +257,7 @@ macro_rules! define_queries {
             // Create an eponymous constructor for each query.
             $(#[allow(nonstandard_style)] $(#[$attr])*
             pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame {
+                opt_remap_env_constness!([$($modifiers)*][key]);
                 let kind = dep_graph::DepKind::$name;
                 let name = stringify!($name);
                 // Disable visible paths printing for performance reasons.
@@ -521,6 +532,7 @@ macro_rules! define_queries_struct {
                 lookup: QueryLookup,
                 mode: QueryMode,
             ) -> Option<query_stored::$name<$tcx>> {
+                opt_remap_env_constness!([$($modifiers)*][key]);
                 let qcx = QueryCtxt { tcx, queries: self };
                 get_query::<queries::$name<$tcx>, _>(qcx, span, key, lookup, mode)
             })*