提交 2624c14a 编写于 作者: N Niko Matsakis

extract the handling of region constraints from queries

上级 bebd3ff6
...@@ -22,15 +22,16 @@ ...@@ -22,15 +22,16 @@
Canonical, CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraint, QueryResult, Canonical, CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraint, QueryResult,
}; };
use infer::region_constraints::{Constraint, RegionConstraintData}; use infer::region_constraints::{Constraint, RegionConstraintData};
use infer::{InferCtxt, InferOk, InferResult}; use infer::{InferCtxt, InferOk, InferResult, RegionObligation};
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use std::fmt::Debug; use std::fmt::Debug;
use syntax::ast;
use traits::query::NoSolution; use traits::query::NoSolution;
use traits::{FulfillmentContext, TraitEngine}; use traits::{FulfillmentContext, TraitEngine};
use traits::{Obligation, ObligationCause, PredicateObligation}; use traits::{Obligation, ObligationCause, PredicateObligation};
use ty::fold::TypeFoldable; use ty::fold::TypeFoldable;
use ty::subst::{Kind, UnpackedKind}; use ty::subst::{Kind, UnpackedKind};
use ty::{self, CanonicalVar}; use ty::{self, CanonicalVar, TyCtxt};
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
...@@ -120,45 +121,8 @@ fn make_query_result<T>( ...@@ -120,45 +121,8 @@ fn make_query_result<T>(
debug!("ambig_errors = {:#?}", ambig_errors); debug!("ambig_errors = {:#?}", ambig_errors);
let region_obligations = self.take_registered_region_obligations(); let region_obligations = self.take_registered_region_obligations();
let region_constraints = self.with_region_constraints(|region_constraints| { let region_constraints = self.with_region_constraints(|region_constraints| {
let RegionConstraintData { make_query_outlives(tcx, region_obligations, region_constraints)
constraints,
verifys,
givens,
} = region_constraints;
assert!(verifys.is_empty());
assert!(givens.is_empty());
let mut outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.collect();
outlives.extend(
region_obligations
.into_iter()
.map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
.map(ty::Binder::dummy), // no bound regions in the code above
);
outlives
}); });
let certainty = if ambig_errors.is_empty() { let certainty = if ambig_errors.is_empty() {
...@@ -358,3 +322,49 @@ fn unify_canonical_vars( ...@@ -358,3 +322,49 @@ fn unify_canonical_vars(
}) })
} }
} }
/// Given the region obligations and constraints scraped from the infcx,
/// creates query region constraints.
fn make_query_outlives<'tcx>(
tcx: TyCtxt<'_, '_, 'tcx>,
region_obligations: Vec<(ast::NodeId, RegionObligation<'tcx>)>,
region_constraints: &RegionConstraintData<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>> {
let RegionConstraintData {
constraints,
verifys,
givens,
} = region_constraints;
assert!(verifys.is_empty());
assert!(givens.is_empty());
let mut outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.collect();
outlives.extend(
region_obligations
.into_iter()
.map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
.map(ty::Binder::dummy), // no bound regions in the code above
);
outlives
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册