diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 70c152b40c0d..acb1d2272ef5 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1352,10 +1352,6 @@ impl_stable_hash_for!( } ); -impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> { - region_outlives, ty_outlives -}); - impl_stable_hash_for!(enum infer::canonical::Certainty { Proven, Ambiguous }); diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 8ea6eb005a14..25f8b5d8c9cc 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -42,7 +42,6 @@ use traits::{Obligation, ObligationCause, PredicateObligation}; use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags}; use ty::subst::{Kind, UnpackedKind}; use ty::fold::{TypeFoldable, TypeFolder}; -use util::captures::Captures; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::FxHashMap; @@ -121,7 +120,7 @@ pub enum CanonicalTyVarKind { #[derive(Clone, Debug)] pub struct QueryResult<'tcx, R> { pub var_values: CanonicalVarValues<'tcx>, - pub region_constraints: QueryRegionConstraints<'tcx>, + pub region_constraints: Vec>, pub certainty: Certainty, pub value: R, } @@ -181,12 +180,7 @@ impl<'tcx, R> Canonical<'tcx, QueryResult<'tcx, R>> { } } -/// Subset of `RegionConstraintData` produced by trait query. -#[derive(Clone, Debug, Default)] -pub struct QueryRegionConstraints<'tcx> { - pub region_outlives: Vec<(Region<'tcx>, Region<'tcx>)>, - pub ty_outlives: Vec<(Ty<'tcx>, Region<'tcx>)>, -} +pub type QueryRegionConstraint<'tcx> = ty::Binder, Region<'tcx>>>; /// Trait implemented by values that can be canonicalized. It mainly /// serves to identify the interning table we will use. @@ -382,35 +376,29 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { &'a self, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>, + unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>], result_subst: &'a CanonicalVarValues<'tcx>, - ) -> impl Iterator> + Captures<'gcx> + 'a { - let QueryRegionConstraints { - region_outlives, - ty_outlives, - } = unsubstituted_region_constraints; - - let region_obligations = region_outlives.iter().map(move |(r1, r2)| { - let r1 = substitute_value(self.tcx, result_subst, r1); + ) -> impl Iterator> + 'a { + Box::new(unsubstituted_region_constraints.iter().map(move |constraint| { + let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below + let k1 = substitute_value(self.tcx, result_subst, k1); let r2 = substitute_value(self.tcx, result_subst, r2); - Obligation::new( - cause.clone(), - param_env, - ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))), - ) - }); + match k1.unpack() { + UnpackedKind::Lifetime(r1) => + Obligation::new( + cause.clone(), + param_env, + ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))), + ), - let ty_obligations = ty_outlives.iter().map(move |(t1, r2)| { - let t1 = substitute_value(self.tcx, result_subst, t1); - let r2 = substitute_value(self.tcx, result_subst, r2); - Obligation::new( - cause.clone(), - param_env, - ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))), - ) - }); - - region_obligations.chain(ty_obligations) + UnpackedKind::Type(t1) => + Obligation::new( + cause.clone(), + param_env, + ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))), + ), + } + })) as Box> } /// Given two sets of values for the same set of canonical variables, unify them. @@ -913,19 +901,6 @@ BraceStructTypeFoldableImpl! { } } -BraceStructTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> { - region_outlives, ty_outlives - } -} - -BraceStructLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> { - type Lifted = QueryRegionConstraints<'tcx>; - region_outlives, ty_outlives - } -} - BraceStructTypeFoldableImpl! { impl<'tcx, R> TypeFoldable<'tcx> for QueryResult<'tcx, R> { var_values, region_constraints, certainty, value diff --git a/src/librustc_traits/util.rs b/src/librustc_traits/util.rs index bff070ab73de..f25906a7bcad 100644 --- a/src/librustc_traits/util.rs +++ b/src/librustc_traits/util.rs @@ -9,8 +9,7 @@ // except according to those terms. use rustc::infer::InferCtxt; -use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraints, - QueryResult}; +use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryResult}; use rustc::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc::traits::{FulfillmentContext, TraitEngine}; use rustc::traits::query::NoSolution; @@ -62,7 +61,7 @@ where let region_obligations = infcx.take_registered_region_obligations(); - let (region_outlives, ty_outlives) = infcx.with_region_constraints(|region_constraints| { + let region_constraints = infcx.with_region_constraints(|region_constraints| { let RegionConstraintData { constraints, verifys, @@ -72,24 +71,32 @@ where assert!(verifys.is_empty()); assert!(givens.is_empty()); - let region_outlives: Vec<_> = constraints + let mut outlives: Vec<_> = constraints .into_iter() .map(|(k, _)| match *k { - Constraint::VarSubVar(v1, v2) => { - (tcx.mk_region(ty::ReVar(v1)), tcx.mk_region(ty::ReVar(v2))) + Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( + tcx.mk_region(ty::ReVar(v1)).into(), + tcx.mk_region(ty::ReVar(v2)), + ), + Constraint::VarSubReg(v1, r2) => { + ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v1)).into(), r2) } - Constraint::VarSubReg(v1, r2) => (tcx.mk_region(ty::ReVar(v1)), r2), - Constraint::RegSubVar(r1, v2) => (r1, tcx.mk_region(ty::ReVar(v2))), - Constraint::RegSubReg(r1, r2) => (r1, r2), + Constraint::RegSubVar(r1, v2) => { + ty::OutlivesPredicate(r1.into(), tcx.mk_region(ty::ReVar(v2))) + } + Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r1.into(), r2), }) + .map(ty::Binder) // no bound regions in the code above .collect(); - let ty_outlives: Vec<_> = region_obligations - .into_iter() - .map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)) - .collect(); + outlives.extend( + region_obligations + .into_iter() + .map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region)) + .map(ty::Binder) // no bound regions in the code above + ); - (region_outlives, ty_outlives) + outlives }); let certainty = if ambig_errors.is_empty() { @@ -100,10 +107,7 @@ where let (canonical_result, _) = infcx.canonicalize_response(&QueryResult { var_values: inference_vars, - region_constraints: QueryRegionConstraints { - region_outlives, - ty_outlives, - }, + region_constraints, certainty, value: answer, });