]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_trait_selection/src/infer.rs
Auto merge of #86765 - cuviper:fuse-less-specialized, r=joshtriplett
[rust.git] / compiler / rustc_trait_selection / src / infer.rs
index a9ffb5542b6df6aa4c36b31125145542e33a1f64..9fc907da2653e39474e300c3822a741dd2ab1d41 100644 (file)
@@ -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 @@ fn partially_normalize_associated_types_in<T>(
     ) -> 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 @@ fn partially_normalize_associated_types_in<T>(
         );
         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> {