diff options
| author | Aman Arora <me@aman-arora.com> | 2021-07-06 05:38:15 -0400 |
|---|---|---|
| committer | Aman Arora <me@aman-arora.com> | 2021-07-06 14:38:10 -0400 |
| commit | 8ef5212effdd5c5b904e51e68fc99c71fb87a1e9 (patch) | |
| tree | 6fbbbcf26fc0fe81791dd1efeb719cba181ffb3d /compiler/rustc_trait_selection | |
| parent | 969a6c2481c41cea793708f7fdd2f96a3397143f (diff) | |
| download | rust-8ef5212effdd5c5b904e51e68fc99c71fb87a1e9.tar.gz rust-8ef5212effdd5c5b904e51e68fc99c71fb87a1e9.zip | |
Make type_implements_trait not a query
Diffstat (limited to 'compiler/rustc_trait_selection')
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(); |
