propagate the pick-constraints through queries
This commit is contained in:
parent
f933e0971b
commit
ddc63ce19f
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user