propagate the pick-constraints through queries

This commit is contained in:
Niko Matsakis 2019-06-05 05:58:08 -04:00
parent f933e0971b
commit ddc63ce19f
6 changed files with 39 additions and 12 deletions

View File

@ -23,6 +23,7 @@
use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
use crate::infer::region_constraints::PickConstraint;
use crate::mir::interpret::ConstValue;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_macros::HashStable;
@ -197,13 +198,14 @@ pub struct QueryResponse<'tcx, R> {
#[derive(Clone, Debug, Default, HashStable)]
pub struct QueryRegionConstraints<'tcx> {
pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
pub pick_constraints: Vec<PickConstraint<'tcx>>,
}
impl QueryRegionConstraints<'_> {
/// Represents an empty (trivially true) set of region
/// constraints.
pub fn is_empty(&self) -> bool {
self.outlives.is_empty()
self.outlives.is_empty() && self.pick_constraints.is_empty()
}
}
@ -555,14 +557,14 @@ BraceStructLiftImpl! {
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
outlives
outlives, pick_constraints
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
type Lifted = QueryRegionConstraints<'tcx>;
outlives
outlives, pick_constraints
}
}

View File

@ -340,7 +340,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let r_c = substitute_value(self.tcx, &result_subst, r_c);
// Screen out `'a: 'a` cases -- we skip the binder here but
// only care the inner values to one another, so they are still at
// only compare the inner values to one another, so they are still at
// consistent binding levels.
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
if k1 != r2.into() {
@ -351,6 +351,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
})
);
// ...also include the query pick constraints.
output_query_region_constraints.pick_constraints.extend(
query_response.value.region_constraints.pick_constraints.iter().map(|p_c| {
substitute_value(self.tcx, &result_subst, p_c)
})
);
let user_result: R =
query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
@ -662,9 +669,6 @@ pub fn make_query_region_constraints<'tcx>(
assert!(verifys.is_empty());
assert!(givens.is_empty());
// FIXME(ndm) -- we have to think about what to do here, perhaps
assert!(pick_constraints.is_empty());
let outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
@ -690,5 +694,5 @@ pub fn make_query_region_constraints<'tcx>(
)
.collect();
QueryRegionConstraints { outlives }
QueryRegionConstraints { outlives, pick_constraints: pick_constraints.clone() }
}

View File

@ -150,7 +150,7 @@ impl Constraint<'_> {
/// ```
/// pick R0 from [O1..On]
/// ```
#[derive(Debug, Clone)]
#[derive(Debug, Clone, HashStable)]
pub struct PickConstraint<'tcx> {
/// the def-id of the opaque type causing this constraint: used for error reporting
pub opaque_type_def_id: DefId,
@ -165,6 +165,19 @@ pub struct PickConstraint<'tcx> {
pub option_regions: Rc<Vec<Region<'tcx>>>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for PickConstraint<'tcx> {
opaque_type_def_id, hidden_ty, pick_region, option_regions
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for PickConstraint<'a> {
type Lifted = PickConstraint<'tcx>;
opaque_type_def_id, hidden_ty, pick_region, option_regions
}
}
/// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or
/// associated type) must outlive the region `R`. `T` is known to
/// outlive `RS`. Therefore, verify that `R <= RS[i]` for some

View File

@ -378,6 +378,13 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
}
}
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc<T> {
type Lifted = Rc<T::Lifted>;
fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
tcx.lift(&**self).map(Rc::new)
}
}
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
type Lifted = Vec<T::Lifted>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {

View File

@ -288,7 +288,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
}
for data in constraint_sets {
let QueryRegionConstraints { outlives } = &*data;
let QueryRegionConstraints { outlives, pick_constraints: _ } = &*data; // TODO
constraint_conversion::ConstraintConversion::new(
self.infcx,
&self.universal_regions,

View File

@ -1100,7 +1100,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
locations, data
);
let QueryRegionConstraints { outlives } = data;
let QueryRegionConstraints { outlives, pick_constraints: _ } = data; // TODO
constraint_conversion::ConstraintConversion::new(
self.infcx,
@ -2511,7 +2511,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
let closure_constraints = QueryRegionConstraints {
outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs)
outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs),
pick_constraints: vec![], // TODO
};
let bounds_mapping = closure_constraints