From 0a0dae0964ee64c9c095f0ab891f0df4a412a253 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 27 Jun 2018 15:17:03 -0400 Subject: [PATCH] pull out `ParamEnvAnd` and remove `QueryKey` --- src/librustc/traits/query/mod.rs | 8 +- src/librustc/traits/query/type_op/eq.rs | 28 ++--- src/librustc/traits/query/type_op/mod.rs | 101 +++++++++--------- .../traits/query/type_op/normalize.rs | 52 ++++----- src/librustc/traits/query/type_op/outlives.rs | 64 +++++++---- .../traits/query/type_op/prove_predicate.rs | 23 ++-- src/librustc/traits/query/type_op/subtype.rs | 27 ++--- .../borrow_check/nll/type_check/liveness.rs | 5 +- .../borrow_check/nll/type_check/mod.rs | 8 +- src/librustc_traits/type_op.rs | 37 +++---- 10 files changed, 172 insertions(+), 181 deletions(-) diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 96034dd935c..54b67edb136 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -34,16 +34,16 @@ Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; pub type CanonicalTypeOpEqGoal<'tcx> = - Canonical<'tcx, type_op::eq::Eq<'tcx>>; + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::eq::Eq<'tcx>>>; pub type CanonicalTypeOpSubtypeGoal<'tcx> = - Canonical<'tcx, type_op::subtype::Subtype<'tcx>>; + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::subtype::Subtype<'tcx>>>; pub type CanonicalTypeOpProvePredicateGoal<'tcx> = - Canonical<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>; + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::prove_predicate::ProvePredicate<'tcx>>>; pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = - Canonical<'tcx, type_op::normalize::Normalize<'tcx, T>>; + Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::normalize::Normalize>>; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct NoSolution; diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 7d05d0a2656..7c35f448a31 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -8,42 +8,36 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult}; +use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult}; use traits::query::Fallible; -use ty::{ParamEnv, Ty, TyCtxt}; +use ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Eq<'tcx> { - pub param_env: ParamEnv<'tcx>, pub a: Ty<'tcx>, pub b: Ty<'tcx>, } impl<'tcx> Eq<'tcx> { - pub fn new(param_env: ParamEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> Self { - Self { param_env, a, b } + pub fn new(a: Ty<'tcx>, b: Ty<'tcx>) -> Self { + Self { a, b } } } impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> { - type QueryKey = Self; type QueryResult = (); - fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result { - if self.a == self.b { - Ok(()) + fn prequery(_tcx: TyCtxt<'_, 'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Eq<'tcx>>) -> Option { + if key.value.a == key.value.b { + Some(()) } else { - Err(self) + None } } - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> { - key.param_env - } - fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonical<'gcx, Eq<'gcx>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { tcx.type_op_eq(canonicalized) } @@ -57,7 +51,6 @@ fn shrink_to_tcx_lifetime( BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for Eq<'tcx> { - param_env, a, b, } @@ -66,12 +59,11 @@ impl<'tcx> TypeFoldable<'tcx> for Eq<'tcx> { BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for Eq<'a> { type Lifted = Eq<'tcx>; - param_env, a, b, } } impl_stable_hash_for! { - struct Eq<'tcx> { param_env, a, b } + struct Eq<'tcx> { a, b } } diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index d89d31726cb..191fc1aabb1 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -8,22 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use infer::canonical::{ - Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint, QueryResult, -}; +use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint, + QueryResult}; use infer::{InferCtxt, InferOk}; use std::fmt; use std::rc::Rc; use traits::query::Fallible; use traits::ObligationCause; use ty::fold::TypeFoldable; -use ty::{Lift, ParamEnv, TyCtxt}; +use ty::{Lift, ParamEnvAnd, TyCtxt}; pub mod custom; pub mod eq; pub mod normalize; pub mod outlives; pub mod prove_predicate; +use self::prove_predicate::ProvePredicate; pub mod subtype; pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug { @@ -38,16 +38,18 @@ fn fully_perform( ) -> Fallible<(Self::Output, Option>>>)>; } -pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized { - type QueryKey: TypeFoldable<'tcx> + Lift<'gcx>; +pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: + fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx> +{ type QueryResult: TypeFoldable<'tcx> + Lift<'gcx>; /// 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; - - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx>; + fn prequery( + tcx: TyCtxt<'_, 'gcx, 'tcx>, + key: &ParamEnvAnd<'tcx, Self>, + ) -> Option; /// Performs the actual query with the canonicalized key -- the /// real work happens here. This method is not given an `infcx` @@ -57,7 +59,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized { /// not captured in the return value. fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Self::QueryKey>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible>; /// Casts a lifted query result (which is in the gcx lifetime) @@ -77,52 +79,53 @@ fn shrink_to_tcx_lifetime( ) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>>; fn fully_perform_into( - self, + query_key: ParamEnvAnd<'tcx, Self>, infcx: &InferCtxt<'_, 'gcx, 'tcx>, output_query_region_constraints: &mut Vec>, ) -> Fallible { - 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::shrink_to_tcx_lifetime(&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) - } + if let Some(result) = QueryTypeOp::prequery(infcx.tcx, &query_key) { + return Ok(result); } + + // 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::shrink_to_tcx_lifetime(&canonical_result); + + let param_env = query_key.param_env; + + 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 () = ProvePredicate::fully_perform_into( + obligation + .param_env + .and(ProvePredicate::new(obligation.predicate)), + infcx, + output_query_region_constraints, + )?; + } + + Ok(value) } } -impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for Q +impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for ParamEnvAnd<'tcx, Q> where Q: QueryTypeOp<'gcx, 'tcx>, { diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index e4d27bccba3..3491b0b4b4e 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -12,45 +12,39 @@ use std::fmt; use traits::query::Fallible; use ty::fold::TypeFoldable; -use ty::{self, Lift, ParamEnv, Ty, TyCtxt}; +use ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -pub struct Normalize<'tcx, T> { - pub param_env: ParamEnv<'tcx>, +pub struct Normalize { pub value: T, } -impl<'tcx, T> Normalize<'tcx, T> +impl<'tcx, T> Normalize where T: fmt::Debug + TypeFoldable<'tcx>, { - pub fn new(param_env: ParamEnv<'tcx>, value: T) -> Self { - Self { param_env, value } + pub fn new(value: T) -> Self { + Self { value } } } -impl<'gcx: 'tcx, 'tcx, T> super::QueryTypeOp<'gcx, 'tcx> for Normalize<'tcx, T> +impl<'gcx: 'tcx, 'tcx, T> super::QueryTypeOp<'gcx, 'tcx> for Normalize where T: Normalizable<'gcx, 'tcx>, { - type QueryKey = Self; type QueryResult = T; - fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result { - if !self.value.has_projections() { - Ok(self.value) + fn prequery(_tcx: TyCtxt<'_, 'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option { + if !key.value.value.has_projections() { + Some(key.value.value) } else { - Err(self) + None } } - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> { - key.param_env - } - fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Self>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { T::type_op_method(tcx, canonicalized) } @@ -62,10 +56,10 @@ fn shrink_to_tcx_lifetime( } } -pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx> { +pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx> + Copy { fn type_op_method( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible>; /// Convert from the `'gcx` (lifted) form of `Self` into the `tcx` @@ -81,7 +75,7 @@ impl Normalizable<'gcx, 'tcx> for Ty<'tcx> { fn type_op_method( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible> { tcx.type_op_normalize_ty(canonicalized) } @@ -99,7 +93,7 @@ impl Normalizable<'gcx, 'tcx> for ty::Predicate<'tcx> { fn type_op_method( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible> { tcx.type_op_normalize_predicate(canonicalized) } @@ -117,7 +111,7 @@ impl Normalizable<'gcx, 'tcx> for ty::PolyFnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible> { tcx.type_op_normalize_poly_fn_sig(canonicalized) } @@ -135,7 +129,7 @@ impl Normalizable<'gcx, 'tcx> for ty::FnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Normalize<'gcx, Self>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible> { tcx.type_op_normalize_fn_sig(canonicalized) } @@ -148,22 +142,20 @@ fn shrink_to_tcx_lifetime( } BraceStructTypeFoldableImpl! { - impl<'tcx, T> TypeFoldable<'tcx> for Normalize<'tcx, T> { - param_env, + impl<'tcx, T> TypeFoldable<'tcx> for Normalize { value, } where T: TypeFoldable<'tcx>, } BraceStructLiftImpl! { - impl<'a, 'tcx, T> Lift<'tcx> for Normalize<'a, T> { - type Lifted = Normalize<'tcx, T::Lifted>; - param_env, + impl<'tcx, T> Lift<'tcx> for Normalize { + type Lifted = Normalize; value, } where T: Lift<'tcx>, } impl_stable_hash_for! { - impl<'tcx, T> for struct Normalize<'tcx, T> { - param_env, value + impl<'tcx, T> for struct Normalize { + value } } diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index cfaed689126..bfb476055c8 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -12,20 +12,16 @@ use traits::query::dropck_outlives::trivial_dropck_outlives; use traits::query::dropck_outlives::DropckOutlivesResult; use traits::query::Fallible; -use ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt}; +use ty::{ParamEnvAnd, Ty, TyCtxt}; -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub struct DropckOutlives<'tcx> { - param_env: ParamEnv<'tcx>, dropped_ty: Ty<'tcx>, } impl<'tcx> DropckOutlives<'tcx> { - pub fn new(param_env: ParamEnv<'tcx>, dropped_ty: Ty<'tcx>) -> Self { - DropckOutlives { - param_env, - dropped_ty, - } + pub fn new(dropped_ty: Ty<'tcx>) -> Self { + DropckOutlives { dropped_ty } } } @@ -33,24 +29,22 @@ impl super::QueryTypeOp<'gcx, 'tcx> for DropckOutlives<'tcx> where 'gcx: 'tcx, { - type QueryKey = ParamEnvAnd<'tcx, Ty<'tcx>>; type QueryResult = DropckOutlivesResult<'tcx>; - fn prequery(self, tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result { - if trivial_dropck_outlives(tcx, self.dropped_ty) { - Ok(DropckOutlivesResult::default()) + fn prequery( + tcx: TyCtxt<'_, 'gcx, 'tcx>, + key: &ParamEnvAnd<'tcx, Self>, + ) -> Option { + if trivial_dropck_outlives(tcx, key.value.dropped_ty) { + Some(DropckOutlivesResult::default()) } else { - Err(self.param_env.and(self.dropped_ty)) + None } } - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> { - key.param_env - } - fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonicalized<'gcx, Self::QueryKey>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { // Subtle: note that we are not invoking // `infcx.at(...).dropck_outlives(...)` here, but rather the @@ -61,6 +55,23 @@ fn perform_query( // good because the interface doesn't give us one (so that we // know we are not registering any subregion relations or // other things). + + // FIXME convert to the type expected by the `dropck_outlives` + // query. This should eventually be fixed by changing the + // *underlying query*. + let Canonical { + variables, + value: + ParamEnvAnd { + param_env, + value: DropckOutlives { dropped_ty }, + }, + } = canonicalized; + let canonicalized = Canonical { + variables, + value: param_env.and(dropped_ty), + }; + tcx.dropck_outlives(canonicalized) } @@ -70,3 +81,20 @@ fn shrink_to_tcx_lifetime( lifted_query_result } } + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for DropckOutlives<'tcx> { + dropped_ty + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for DropckOutlives<'a> { + type Lifted = DropckOutlives<'tcx>; + dropped_ty + } +} + +impl_stable_hash_for! { + struct DropckOutlives<'tcx> { dropped_ty } +} diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index f54710c4805..dfe640f7431 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -8,40 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult}; +use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult}; use traits::query::Fallible; -use ty::{ParamEnv, Predicate, TyCtxt}; +use ty::{ParamEnvAnd, Predicate, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ProvePredicate<'tcx> { - pub param_env: ParamEnv<'tcx>, pub predicate: Predicate<'tcx>, } impl<'tcx> ProvePredicate<'tcx> { - pub fn new(param_env: ParamEnv<'tcx>, predicate: Predicate<'tcx>) -> Self { + pub fn new(predicate: Predicate<'tcx>) -> Self { ProvePredicate { - param_env, predicate, } } } impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> { - type QueryKey = Self; type QueryResult = (); - fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result { - Err(self) - } - - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> { - key.param_env + fn prequery(_tcx: TyCtxt<'_, 'gcx, 'tcx>, _key: &ParamEnvAnd<'tcx, Self>) -> Option { + None } fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonical<'gcx, ProvePredicate<'gcx>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { tcx.type_op_prove_predicate(canonicalized) } @@ -55,7 +48,6 @@ fn shrink_to_tcx_lifetime( BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for ProvePredicate<'tcx> { - param_env, predicate, } } @@ -63,11 +55,10 @@ impl<'tcx> TypeFoldable<'tcx> for ProvePredicate<'tcx> { BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ProvePredicate<'a> { type Lifted = ProvePredicate<'tcx>; - param_env, predicate, } } impl_stable_hash_for! { - struct ProvePredicate<'tcx> { param_env, predicate } + struct ProvePredicate<'tcx> { predicate } } diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index e1589e1a9b6..db535e3dd13 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -8,21 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use infer::canonical::{Canonical, CanonicalizedQueryResult, QueryResult}; +use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult}; use traits::query::Fallible; -use ty::{ParamEnv, Ty, TyCtxt}; +use ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Subtype<'tcx> { - pub param_env: ParamEnv<'tcx>, pub sub: Ty<'tcx>, pub sup: Ty<'tcx>, } impl<'tcx> Subtype<'tcx> { - pub fn new(param_env: ParamEnv<'tcx>, sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { + pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { Self { - param_env, sub, sup, } @@ -30,24 +28,19 @@ pub fn new(param_env: ParamEnv<'tcx>, sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { } impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> { - type QueryKey = Self; type QueryResult = (); - fn prequery(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<(), Self::QueryKey> { - if self.sub == self.sup { - Ok(()) + fn prequery(_tcx: TyCtxt<'_, 'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<()> { + if key.value.sub == key.value.sup { + Some(()) } else { - Err(self) + None } } - fn param_env(key: &Self::QueryKey) -> ParamEnv<'tcx> { - key.param_env - } - fn perform_query( tcx: TyCtxt<'_, 'gcx, 'tcx>, - canonicalized: Canonical<'gcx, Subtype<'gcx>>, + canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { tcx.type_op_subtype(canonicalized) } @@ -61,7 +54,6 @@ fn shrink_to_tcx_lifetime( BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for Subtype<'tcx> { - param_env, sub, sup, } @@ -70,12 +62,11 @@ impl<'tcx> TypeFoldable<'tcx> for Subtype<'tcx> { BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for Subtype<'a> { type Lifted = Subtype<'tcx>; - param_env, sub, sup, } } impl_stable_hash_for! { - struct Subtype<'tcx> { param_env, sub, sup } + struct Subtype<'tcx> { sub, sup } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index 73ed695bfb2..f27de92c621 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -13,10 +13,10 @@ use dataflow::move_paths::{HasMoveData, MoveData}; use dataflow::MaybeInitializedPlaces; use dataflow::{FlowAtLocation, FlowsAtLocation}; -use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::infer::canonical::QueryRegionConstraint; use rustc::mir::Local; use rustc::mir::{BasicBlock, Location, Mir}; +use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; use rustc::ty::{Ty, TypeFoldable}; @@ -223,7 +223,8 @@ fn compute_drop_data( debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); let param_env = cx.param_env; - let (dropck_result, region_constraint_data) = DropckOutlives::new(param_env, dropped_ty) + let (dropck_result, region_constraint_data) = param_env + .and(DropckOutlives::new(dropped_ty)) .fully_perform(cx.infcx) .unwrap(); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 843fadf6227..39f6c6a6864 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -778,13 +778,13 @@ fn sub_types( let param_env = self.param_env; self.fully_perform_op( locations, - type_op::subtype::Subtype::new(param_env, sub, sup), + param_env.and(type_op::subtype::Subtype::new(sub, sup)), ) } fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallible<()> { let param_env = self.param_env; - self.fully_perform_op(locations, type_op::eq::Eq::new(param_env, b, a)) + self.fully_perform_op(locations, param_env.and(type_op::eq::Eq::new(b, a))) } fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { @@ -1576,7 +1576,7 @@ fn prove_predicate(&mut self, predicate: ty::Predicate<'tcx>, location: Location let param_env = self.param_env; self.fully_perform_op( location.at_self(), - type_op::prove_predicate::ProvePredicate::new(param_env, predicate), + param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)), ).unwrap_or_else(|NoSolution| { span_mirbug!(self, NoSolution, "could not prove {:?}", predicate); }) @@ -1616,7 +1616,7 @@ fn normalize(&mut self, value: T, location: impl ToLocations) -> T let param_env = self.param_env; self.fully_perform_op( location.to_locations(), - type_op::normalize::Normalize::new(param_env, value), + param_env.and(type_op::normalize::Normalize::new(value)), ).unwrap_or_else(|NoSolution| { span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value); value diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs index 9e8640a32de..99406082222 100644 --- a/src/librustc_traits/type_op.rs +++ b/src/librustc_traits/type_op.rs @@ -17,7 +17,7 @@ use rustc::traits::query::{Fallible, NoSolution}; use rustc::traits::{Obligation, Normalized, ObligationCause}; use rustc::ty::query::Providers; -use rustc::ty::{FnSig, Lift, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{ParamEnvAnd, FnSig, Lift, PolyFnSig, Predicate, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::sync::Lrc; use std::fmt; @@ -36,22 +36,23 @@ fn type_op_eq<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Eq<'tcx>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>, ) -> Result>>, NoSolution> { tcx.infer_ctxt() - .enter_canonical_trait_query(&canonicalized, |infcx, Eq { param_env, a, b }| { + .enter_canonical_trait_query(&canonicalized, |infcx, key| { + let (param_env, Eq { a, b }) = key.into_parts(); Ok(infcx.at(&ObligationCause::dummy(), param_env).eq(a, b)?) }) } fn type_op_normalize( infcx: &InferCtxt<'_, 'gcx, 'tcx>, - key: Normalize<'tcx, T>, + key: ParamEnvAnd<'tcx, Normalize>, ) -> Fallible> where T: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>, { - let Normalize { param_env, value } = key; + let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = infcx .at(&ObligationCause::dummy(), param_env) .normalize(&value)?; @@ -60,7 +61,7 @@ fn type_op_normalize( fn type_op_normalize_ty( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Normalize<'tcx, Ty<'tcx>>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) @@ -68,7 +69,7 @@ fn type_op_normalize_ty( fn type_op_normalize_predicate( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Normalize<'tcx, Predicate<'tcx>>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) @@ -76,7 +77,7 @@ fn type_op_normalize_predicate( fn type_op_normalize_fn_sig( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Normalize<'tcx, FnSig<'tcx>>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) @@ -84,7 +85,7 @@ fn type_op_normalize_fn_sig( fn type_op_normalize_poly_fn_sig( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Normalize<'tcx, PolyFnSig<'tcx>>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>>, ) -> Result>>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, type_op_normalize) @@ -92,16 +93,11 @@ fn type_op_normalize_poly_fn_sig( fn type_op_subtype<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, Subtype<'tcx>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>, ) -> Result>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query( - &canonicalized, - |infcx, - Subtype { - param_env, - sub, - sup, - }| { + &canonicalized, |infcx, key| { + let (param_env, Subtype { sub, sup }) = key.into_parts(); Ok(infcx .at(&ObligationCause::dummy(), param_env) .sup(sup, sub)?) @@ -111,14 +107,11 @@ fn type_op_subtype<'tcx>( fn type_op_prove_predicate<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, - canonicalized: Canonical<'tcx, ProvePredicate<'tcx>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, ) -> Result>>, NoSolution> { tcx.infer_ctxt() .enter_canonical_trait_query(&canonicalized, |_infcx, key| { - let ProvePredicate { - param_env, - predicate, - } = key; + let (param_env, ProvePredicate { predicate }) = key.into_parts(); Ok(InferOk { value: (), obligations: vec![Obligation::new( -- 2.44.0