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;
#[derive(Clone, Debug)]
pub struct QueryResult<'tcx, R> {
pub var_values: CanonicalVarValues<'tcx>,
- pub region_constraints: QueryRegionConstraints<'tcx>,
+ pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
pub certainty: Certainty,
pub value: 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<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
/// Trait implemented by values that can be canonicalized. It mainly
/// serves to identify the interning table we will use.
&'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<Item = PredicateObligation<'tcx>> + 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);
- let r2 = substitute_value(self.tcx, result_subst, r2);
- 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);
+ ) -> impl Iterator<Item = PredicateObligation<'tcx>> + '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::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
- )
- });
-
- region_obligations.chain(ty_obligations)
+ match k1.unpack() {
+ UnpackedKind::Lifetime(r1) =>
+ Obligation::new(
+ cause.clone(),
+ param_env,
+ ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))),
+ ),
+
+ UnpackedKind::Type(t1) =>
+ Obligation::new(
+ cause.clone(),
+ param_env,
+ ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
+ ),
+ }
+ })) as Box<dyn Iterator<Item = _>>
}
/// Given two sets of values for the same set of canonical variables, unify them.
}
}
-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
// 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;
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,
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() {
let (canonical_result, _) = infcx.canonicalize_response(&QueryResult {
var_values: inference_vars,
- region_constraints: QueryRegionConstraints {
- region_outlives,
- ty_outlives,
- },
+ region_constraints,
certainty,
value: answer,
});