Make type_implements_trait not a query
This commit is contained in:
parent
969a6c2481
commit
8ef5212eff
10 changed files with 141 additions and 107 deletions
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue