convert query-type-op to create query-region-constraint directly
This commit is contained in:
parent
a583269af5
commit
82169b6134
@ -17,7 +17,6 @@
|
||||
//!
|
||||
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
|
||||
|
||||
use either::Either;
|
||||
use infer::canonical::substitute::substitute_value;
|
||||
use infer::canonical::{
|
||||
Canonical, CanonicalVarKind, CanonicalVarValues, CanonicalizedQueryResult, Certainty,
|
||||
@ -29,7 +28,6 @@ use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use std::fmt::Debug;
|
||||
use std::iter::once;
|
||||
use syntax::ast;
|
||||
use traits::query::NoSolution;
|
||||
use traits::{FulfillmentContext, TraitEngine};
|
||||
@ -191,9 +189,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
pub fn instantiate_nll_query_result_and_region_obligations<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &CanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
) -> Vec<QueryRegionConstraint<'tcx>>
|
||||
output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
|
||||
) -> InferResult<'tcx, R>
|
||||
where
|
||||
R: Debug + TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -210,52 +210,59 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||
// Compute `QueryRegionConstraint` values that unify each of
|
||||
// the original values `v_o` that was canonicalized into a
|
||||
// variable...
|
||||
let qrc_from_unify = original_values.var_values.iter_enumerated().flat_map(
|
||||
|(index, original_value)| {
|
||||
// ...with the value `v_r` of that variable from the query.
|
||||
let result_value =
|
||||
query_result
|
||||
.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index]);
|
||||
match (original_value.unpack(), result_value.unpack()) {
|
||||
(
|
||||
UnpackedKind::Lifetime(ty::ReErased),
|
||||
UnpackedKind::Lifetime(ty::ReErased),
|
||||
) => {
|
||||
// no action needed
|
||||
Either::Left(None.into_iter())
|
||||
}
|
||||
let mut obligations = vec![];
|
||||
|
||||
(UnpackedKind::Lifetime(v_o), UnpackedKind::Lifetime(v_r)) => {
|
||||
// To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
|
||||
Either::Right(
|
||||
once(ty::OutlivesPredicate(v_o.into(), v_r))
|
||||
.chain(once(ty::OutlivesPredicate(v_r.into(), v_o)))
|
||||
.map(ty::Binder::dummy),
|
||||
)
|
||||
}
|
||||
for (index, original_value) in original_values.var_values.iter_enumerated() {
|
||||
// ...with the value `v_r` of that variable from the query.
|
||||
let result_value = query_result
|
||||
.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index]);
|
||||
match (original_value.unpack(), result_value.unpack()) {
|
||||
(UnpackedKind::Lifetime(ty::ReErased), UnpackedKind::Lifetime(ty::ReErased)) => {
|
||||
// no action needed
|
||||
}
|
||||
|
||||
(UnpackedKind::Type(_), _) | (_, UnpackedKind::Type(_)) => {
|
||||
// in NLL queries, we do not expect `type` results.
|
||||
bug!(
|
||||
"unexpected type in NLL query: cannot unify {:?} and {:?}",
|
||||
original_value,
|
||||
result_value,
|
||||
);
|
||||
(UnpackedKind::Lifetime(v_o), UnpackedKind::Lifetime(v_r)) => {
|
||||
// To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
|
||||
if v_o != v_r {
|
||||
output_query_region_constraints
|
||||
.push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)));
|
||||
output_query_region_constraints
|
||||
.push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)));
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
(UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => {
|
||||
let ok = self.at(cause, param_env).eq(v1, v2)?;
|
||||
obligations.extend(ok.into_obligations());
|
||||
}
|
||||
|
||||
_ => {
|
||||
bug!(
|
||||
"kind mismatch, cannot unify {:?} and {:?}",
|
||||
original_value,
|
||||
result_value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ...also include the other query region constraints from the query.
|
||||
let qrc_from_result = query_result.value.region_constraints.iter().map(|r_c| {
|
||||
r_c.map_bound(|ty::OutlivesPredicate(k1, r2)| {
|
||||
output_query_region_constraints.reserve(query_result.value.region_constraints.len());
|
||||
for r_c in query_result.value.region_constraints.iter() {
|
||||
output_query_region_constraints.push(r_c.map_bound(|ty::OutlivesPredicate(k1, r2)| {
|
||||
let k1 = substitute_value(self.tcx, &result_subst, &k1);
|
||||
let r2 = substitute_value(self.tcx, &result_subst, &r2);
|
||||
ty::OutlivesPredicate(k1, r2)
|
||||
})
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
qrc_from_unify.chain(qrc_from_result).collect()
|
||||
let user_result: R =
|
||||
query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
|
||||
|
||||
Ok(InferOk {
|
||||
value: user_result,
|
||||
obligations,
|
||||
})
|
||||
}
|
||||
|
||||
/// Given the original values and the (canonicalized) result from
|
||||
|
@ -9,9 +9,14 @@
|
||||
// except according to those terms.
|
||||
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use traits::query::Fallible;
|
||||
use ty::TyCtxt;
|
||||
use std::fmt;
|
||||
use traits::query::Fallible;
|
||||
|
||||
use infer::canonical::query_result;
|
||||
use infer::canonical::QueryRegionConstraint;
|
||||
use std::rc::Rc;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use traits::{ObligationCause, TraitEngine};
|
||||
|
||||
pub struct CustomTypeOp<F, G> {
|
||||
closure: F,
|
||||
@ -38,12 +43,18 @@ where
|
||||
{
|
||||
type Output = R;
|
||||
|
||||
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
|
||||
Err(self)
|
||||
}
|
||||
/// Processes the operation and all resulting obligations,
|
||||
/// returning the final result along with any region constraints
|
||||
/// (they will be given over to the NLL region solver).
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
|
||||
if cfg!(debug_assertions) {
|
||||
info!("fully_perform({:?})", self);
|
||||
}
|
||||
|
||||
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>> {
|
||||
Ok((self.closure)(infcx)?)
|
||||
scrape_region_constraints(infcx, || Ok((self.closure)(infcx)?))
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,3 +66,35 @@ where
|
||||
write!(f, "{}", (self.description)())
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes `op` and then scrapes out all the "old style" region
|
||||
/// constraints that result, creating query-region-constraints.
|
||||
fn scrape_region_constraints<'gcx, 'tcx, R>(
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
|
||||
) -> Fallible<(R, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
|
||||
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
||||
let dummy_body_id = ObligationCause::dummy().body_id;
|
||||
let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?;
|
||||
debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id));
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
if let Err(e) = fulfill_cx.select_all_or_error(infcx) {
|
||||
infcx.tcx.sess.diagnostic().delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!("errors selecting obligation during MIR typeck: {:?}", e),
|
||||
);
|
||||
}
|
||||
|
||||
let region_obligations = infcx.take_registered_region_obligations();
|
||||
|
||||
let region_constraint_data = infcx.take_and_reset_region_constraints();
|
||||
|
||||
let outlives =
|
||||
query_result::make_query_outlives(infcx.tcx, region_obligations, ®ion_constraint_data);
|
||||
|
||||
if outlives.is_empty() {
|
||||
Ok((value, None))
|
||||
} else {
|
||||
Ok((value, Some(Rc::new(outlives))))
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult};
|
||||
use traits::query::Fallible;
|
||||
use ty::{self, ParamEnv, Ty, TyCtxt};
|
||||
use ty::{ParamEnv, Ty, TyCtxt};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Eq<'tcx> {
|
||||
@ -29,7 +29,7 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
|
||||
type QueryKey = Self;
|
||||
type QueryResult = ();
|
||||
|
||||
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self> {
|
||||
fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self> {
|
||||
if self.a == self.b {
|
||||
Ok(())
|
||||
} else {
|
||||
@ -37,12 +37,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_query_key(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> {
|
||||
key.param_env
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
|
@ -8,16 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::query_result;
|
||||
use infer::canonical::{
|
||||
Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint, QueryResult,
|
||||
};
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use traits::query::Fallible;
|
||||
use traits::{ObligationCause, TraitEngine};
|
||||
use traits::ObligationCause;
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::{Lift, ParamEnv, TyCtxt};
|
||||
|
||||
@ -31,89 +29,25 @@ pub mod subtype;
|
||||
pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
|
||||
type Output;
|
||||
|
||||
/// Micro-optimization: returns `Ok(x)` if we can trivially
|
||||
/// produce the output, else returns `Err(self)` back.
|
||||
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self>;
|
||||
|
||||
/// Given an infcx, performs **the kernel** of the operation: this does the
|
||||
/// key action and then, optionally, returns a set of obligations which must be proven.
|
||||
///
|
||||
/// This method is not meant to be invoked directly: instead, one
|
||||
/// should use `fully_perform`, which will take those resulting
|
||||
/// obligations and prove them, and then process the combined
|
||||
/// results into region obligations which are returned.
|
||||
fn perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
) -> Fallible<InferOk<'tcx, Self::Output>>;
|
||||
|
||||
/// Processes the operation and all resulting obligations,
|
||||
/// returning the final result along with any region constraints
|
||||
/// (they will be given over to the NLL region solver).
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
|
||||
match self.trivial_noop(infcx.tcx) {
|
||||
Ok(r) => Ok((r, None)),
|
||||
Err(op) => op.fully_perform_nontrivial(infcx),
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for `fully_perform` that handles the nontrivial cases.
|
||||
#[inline(never)] // just to help with profiling
|
||||
fn fully_perform_nontrivial(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
|
||||
if cfg!(debug_assertions) {
|
||||
info!(
|
||||
"fully_perform_op_and_get_region_constraint_data({:?})",
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
||||
let dummy_body_id = ObligationCause::dummy().body_id;
|
||||
let InferOk { value, obligations } = infcx.commit_if_ok(|_| self.perform(infcx))?;
|
||||
debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id));
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
if let Err(e) = fulfill_cx.select_all_or_error(infcx) {
|
||||
infcx.tcx.sess.diagnostic().delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!("errors selecting obligation during MIR typeck: {:?}", e),
|
||||
);
|
||||
}
|
||||
|
||||
let region_obligations = infcx.take_registered_region_obligations();
|
||||
|
||||
let region_constraint_data = infcx.take_and_reset_region_constraints();
|
||||
|
||||
let outlives = query_result::make_query_outlives(
|
||||
infcx.tcx,
|
||||
region_obligations,
|
||||
®ion_constraint_data,
|
||||
);
|
||||
|
||||
if outlives.is_empty() {
|
||||
Ok((value, None))
|
||||
} else {
|
||||
Ok((value, Some(Rc::new(outlives))))
|
||||
}
|
||||
}
|
||||
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)>;
|
||||
}
|
||||
|
||||
pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized {
|
||||
type QueryKey: TypeFoldable<'tcx> + Lift<'gcx>;
|
||||
type QueryResult: TypeFoldable<'tcx> + Lift<'gcx>;
|
||||
|
||||
/// Micro-optimization: returns `Ok(x)` if we can trivially
|
||||
/// produce the output, else returns `Err(self)` back.
|
||||
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self>;
|
||||
/// Either converts `self` directly into a `QueryResult` (for
|
||||
/// simple cases) or into a `QueryKey` (for more complex cases
|
||||
/// where we actually have work to do).
|
||||
fn prequery(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self::QueryKey>;
|
||||
|
||||
fn into_query_key(self) -> Self::QueryKey;
|
||||
|
||||
fn param_env(&self) -> ParamEnv<'tcx>;
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx>;
|
||||
|
||||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
@ -130,6 +64,51 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized {
|
||||
fn upcast_result(
|
||||
lifted_query_result: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>>;
|
||||
|
||||
fn fully_perform_into(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
|
||||
) -> Fallible<Self::QueryResult> {
|
||||
match QueryTypeOp::prequery(self, infcx.tcx) {
|
||||
Ok(result) => Ok(result),
|
||||
Err(query_key) => {
|
||||
// FIXME(#33684) -- We need to use
|
||||
// `canonicalize_hr_query_hack` here because of things
|
||||
// like the subtype query, which go awry around
|
||||
// `'static` otherwise.
|
||||
let (canonical_self, canonical_var_values) =
|
||||
infcx.canonicalize_hr_query_hack(&query_key);
|
||||
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
|
||||
let canonical_result = Self::upcast_result(&canonical_result);
|
||||
|
||||
let param_env = Self::param_env(&query_key);
|
||||
|
||||
let InferOk { value, obligations } = infcx
|
||||
.instantiate_nll_query_result_and_region_obligations(
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
&canonical_var_values,
|
||||
canonical_result,
|
||||
output_query_region_constraints,
|
||||
)?;
|
||||
|
||||
// Typically, instantiating NLL query results does not
|
||||
// create obligations. However, in some cases there
|
||||
// are unresolved type variables, and unify them *can*
|
||||
// create obligations. In that case, we have to go
|
||||
// fulfill them. We do this via a (recursive) query.
|
||||
for obligation in obligations {
|
||||
let () = prove_predicate::ProvePredicate::new(
|
||||
obligation.param_env,
|
||||
obligation.predicate,
|
||||
).fully_perform_into(infcx, output_query_region_constraints)?;
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for Q
|
||||
@ -138,38 +117,21 @@ where
|
||||
{
|
||||
type Output = Q::QueryResult;
|
||||
|
||||
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
|
||||
QueryTypeOp::trivial_noop(self, tcx)
|
||||
}
|
||||
|
||||
fn perform(
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
) -> Fallible<InferOk<'tcx, Self::Output>> {
|
||||
let param_env = self.param_env();
|
||||
) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
|
||||
let mut qrc = vec![];
|
||||
let r = Q::fully_perform_into(self, infcx, &mut qrc)?;
|
||||
|
||||
// FIXME(#33684) -- We need to use
|
||||
// `canonicalize_hr_query_hack` here because of things like
|
||||
// the subtype query, which go awry around `'static`
|
||||
// otherwise.
|
||||
let query_key = self.into_query_key();
|
||||
let (canonical_self, canonical_var_values) = infcx.canonicalize_hr_query_hack(&query_key);
|
||||
let canonical_result = Q::perform_query(infcx.tcx, canonical_self)?;
|
||||
// Promote the final query-region-constraints into a
|
||||
// (optional) ref-counted vector:
|
||||
let opt_qrc = if qrc.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Rc::new(qrc))
|
||||
};
|
||||
|
||||
// FIXME: This is not the most efficient setup. The
|
||||
// `instantiate_query_result_and_region_obligations` basically
|
||||
// takes the `QueryRegionConstraint` values that we ultimately
|
||||
// want to use and converts them into obligations. We return
|
||||
// those to our caller, which will convert them into AST
|
||||
// region constraints; we then convert *those* back into
|
||||
// `QueryRegionConstraint` and ultimately into NLL
|
||||
// constraints. We should cut out the middleman but that will
|
||||
// take a bit of refactoring.
|
||||
Ok(infcx.instantiate_query_result_and_region_obligations(
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
&canonical_var_values,
|
||||
Q::upcast_result(&canonical_result),
|
||||
)?)
|
||||
Ok((r, opt_qrc))
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ where
|
||||
type QueryKey = Self;
|
||||
type QueryResult = T;
|
||||
|
||||
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<T, Self> {
|
||||
fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<T, Self> {
|
||||
if !self.value.has_projections() {
|
||||
Ok(self.value)
|
||||
} else {
|
||||
@ -44,12 +44,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn into_query_key(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> {
|
||||
key.param_env
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
|
@ -36,20 +36,16 @@ where
|
||||
type QueryKey = ParamEnvAnd<'tcx, Ty<'tcx>>;
|
||||
type QueryResult = DropckOutlivesResult<'tcx>;
|
||||
|
||||
fn trivial_noop(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self> {
|
||||
fn prequery(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self::QueryKey> {
|
||||
if trivial_dropck_outlives(tcx, self.dropped_ty) {
|
||||
Ok(DropckOutlivesResult::default())
|
||||
} else {
|
||||
Err(self)
|
||||
Err(self.param_env.and(self.dropped_ty))
|
||||
}
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
}
|
||||
|
||||
fn into_query_key(self) -> Self::QueryKey {
|
||||
self.param_env.and(self.dropped_ty)
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> {
|
||||
key.param_env
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
|
@ -31,16 +31,12 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
|
||||
type QueryKey = Self;
|
||||
type QueryResult = ();
|
||||
|
||||
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self> {
|
||||
fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::QueryResult, Self::QueryKey> {
|
||||
Err(self)
|
||||
}
|
||||
|
||||
fn into_query_key(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> {
|
||||
key.param_env
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
|
@ -33,7 +33,7 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
|
||||
type QueryKey = Self;
|
||||
type QueryResult = ();
|
||||
|
||||
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<(), Self> {
|
||||
fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<(), Self::QueryKey> {
|
||||
if self.sub == self.sup {
|
||||
Ok(())
|
||||
} else {
|
||||
@ -41,12 +41,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_query_key(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> {
|
||||
key.param_env
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
|
Loading…
Reference in New Issue
Block a user