about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
diff options
context:
space:
mode:
authorAman Arora <me@aman-arora.com>2021-07-06 05:38:15 -0400
committerAman Arora <me@aman-arora.com>2021-07-06 14:38:10 -0400
commit8ef5212effdd5c5b904e51e68fc99c71fb87a1e9 (patch)
tree6fbbbcf26fc0fe81791dd1efeb719cba181ffb3d /compiler/rustc_trait_selection
parent969a6c2481c41cea793708f7fdd2f96a3397143f (diff)
downloadrust-8ef5212effdd5c5b904e51e68fc99c71fb87a1e9.tar.gz
rust-8ef5212effdd5c5b904e51e68fc99c71fb87a1e9.zip
Make type_implements_trait not a query
Diffstat (limited to 'compiler/rustc_trait_selection')
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs45
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs41
3 files changed, 48 insertions, 43 deletions
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index a9ffb5542b6..9fc907da265 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -1,13 +1,18 @@
+use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::outlives_bounds::InferCtxtExt as _;
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 
 use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse};
 use rustc_middle::traits::query::Fallible;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::ToPredicate;
+use rustc_middle::ty::WithConstness;
 use rustc_middle::ty::{self, Ty, TypeFoldable};
 use rustc_span::{Span, DUMMY_SP};
 
@@ -32,8 +37,22 @@ pub trait InferCtxtExt<'tcx> {
     ) -> InferOk<'tcx, T>
     where
         T: TypeFoldable<'tcx>;
-}
 
+    /// Check whether a `ty` implements given trait(trait_def_id).
+    /// The inputs are:
+    ///
+    /// - the def-id of the trait
+    /// - the self type
+    /// - the *other* type parameters of the trait, excluding the self-type
+    /// - the parameter environment
+    fn type_implements_trait(
+        &self,
+        trait_def_id: DefId,
+        ty: Ty<'tcx>,
+        params: SubstsRef<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> traits::EvaluationResult;
+}
 impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
     fn type_is_copy_modulo_regions(
         &self,
@@ -79,6 +98,30 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
         );
         InferOk { value, obligations }
     }
+
+    fn type_implements_trait(
+        &self,
+        trait_def_id: DefId,
+        ty: Ty<'tcx>,
+        params: SubstsRef<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> traits::EvaluationResult {
+        debug!(
+            "type_implements_trait: trait_def_id={:?}, type={:?}, params={:?}, param_env={:?}",
+            trait_def_id, ty, params, param_env
+        );
+
+        let trait_ref =
+            ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) };
+
+        let obligation = traits::Obligation {
+            cause: traits::ObligationCause::dummy(),
+            param_env,
+            recursion_depth: 0,
+            predicate: trait_ref.without_const().to_predicate(self.tcx),
+        };
+        self.evaluate_obligation_no_overflow(&obligation)
+    }
 }
 
 pub trait InferCtxtBuilderExt<'tcx> {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 9bc3d398f72..cca40ff1ce6 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -28,6 +28,7 @@ use rustc_target::spec::abi;
 use std::fmt;
 
 use super::InferCtxtPrivExt;
+use crate::infer::InferCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 
@@ -2349,12 +2350,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 }
                 let self_ty = self.tcx.erase_regions(self_ty);
 
-                let impls_future = self.tcx.type_implements_trait((
+                let impls_future = self.type_implements_trait(
                     future_trait,
                     self_ty.skip_binder(),
                     ty::List::empty(),
                     obligation.param_env,
-                ));
+                );
 
                 let item_def_id = self
                     .tcx
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index e48aab6f46f..3a80e720e8c 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -31,7 +31,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
 use rustc_middle::ty::{
-    self, GenericParamDefKind, ParamEnv, ToPredicate, Ty, TyCtxt, VtblEntry, WithConstness,
+    self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry, WithConstness,
     COMMON_VTABLE_ENTRIES,
 };
 use rustc_span::Span;
@@ -541,44 +541,6 @@ fn vtable_trait_first_method_offset<'tcx>(
     vtable_base
 }
 
-/// Check whether a `ty` implements given trait(trait_def_id).
-/// See query definition for details.
-fn type_implements_trait<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    key: (
-        DefId,    // trait_def_id,
-        Ty<'tcx>, // type
-        SubstsRef<'tcx>,
-        ParamEnv<'tcx>,
-    ),
-) -> EvaluationResult {
-    let (trait_def_id, ty, params, param_env) = key;
-
-    debug!(
-        "type_implements_trait: trait_def_id={:?}, type={:?}, params={:?}, param_env={:?}",
-        trait_def_id, ty, params, param_env
-    );
-
-    let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, params) };
-
-    // FIXME(#86868): If there are inference variables anywhere, just give up and assume
-    // we don't know the answer. This works around the ICEs that would result from
-    // using those inference variables within the `infer_ctxt` we create below.
-    // Really we should be using canonicalized variables, or perhaps removing
-    // this query altogether.
-    if (trait_ref, param_env).needs_infer() {
-        return EvaluationResult::EvaluatedToUnknown;
-    }
-
-    let obligation = Obligation {
-        cause: ObligationCause::dummy(),
-        param_env,
-        recursion_depth: 0,
-        predicate: trait_ref.without_const().to_predicate(tcx),
-    };
-    tcx.infer_ctxt().enter(|infcx| infcx.evaluate_obligation_no_overflow(&obligation))
-}
-
 pub fn provide(providers: &mut ty::query::Providers) {
     object_safety::provide(providers);
     structural_match::provide(providers);
@@ -587,7 +549,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
         specializes: specialize::specializes,
         codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
         vtable_entries,
-        type_implements_trait,
         subst_and_check_impossible_predicates,
         mir_abstract_const: |tcx, def_id| {
             let def_id = def_id.expect_local();