Skip to content

Commit c8a5285

Browse files
committed
create a QueryRegionConstraint type
Chalk wants to be able to pass these constraints around. Also, the form we were using in our existing queries was not as general as we are going to need.
1 parent 3aa1085 commit c8a5285

File tree

3 files changed

+45
-70
lines changed

3 files changed

+45
-70
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,10 +1352,6 @@ impl_stable_hash_for!(
13521352
}
13531353
);
13541354

1355-
impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> {
1356-
region_outlives, ty_outlives
1357-
});
1358-
13591355
impl_stable_hash_for!(enum infer::canonical::Certainty {
13601356
Proven, Ambiguous
13611357
});

src/librustc/infer/canonical.rs

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ use traits::{Obligation, ObligationCause, PredicateObligation};
4242
use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags};
4343
use ty::subst::{Kind, UnpackedKind};
4444
use ty::fold::{TypeFoldable, TypeFolder};
45-
use util::captures::Captures;
4645

4746
use rustc_data_structures::indexed_vec::IndexVec;
4847
use rustc_data_structures::fx::FxHashMap;
@@ -121,7 +120,7 @@ pub enum CanonicalTyVarKind {
121120
#[derive(Clone, Debug)]
122121
pub struct QueryResult<'tcx, R> {
123122
pub var_values: CanonicalVarValues<'tcx>,
124-
pub region_constraints: QueryRegionConstraints<'tcx>,
123+
pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
125124
pub certainty: Certainty,
126125
pub value: R,
127126
}
@@ -181,12 +180,7 @@ impl<'tcx, R> Canonical<'tcx, QueryResult<'tcx, R>> {
181180
}
182181
}
183182

184-
/// Subset of `RegionConstraintData` produced by trait query.
185-
#[derive(Clone, Debug, Default)]
186-
pub struct QueryRegionConstraints<'tcx> {
187-
pub region_outlives: Vec<(Region<'tcx>, Region<'tcx>)>,
188-
pub ty_outlives: Vec<(Ty<'tcx>, Region<'tcx>)>,
189-
}
183+
pub type QueryRegionConstraint<'tcx> = ty::Binder<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
190184

191185
/// Trait implemented by values that can be canonicalized. It mainly
192186
/// serves to identify the interning table we will use.
@@ -382,35 +376,29 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
382376
&'a self,
383377
cause: &'a ObligationCause<'tcx>,
384378
param_env: ty::ParamEnv<'tcx>,
385-
unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>,
379+
unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
386380
result_subst: &'a CanonicalVarValues<'tcx>,
387-
) -> impl Iterator<Item = PredicateObligation<'tcx>> + Captures<'gcx> + 'a {
388-
let QueryRegionConstraints {
389-
region_outlives,
390-
ty_outlives,
391-
} = unsubstituted_region_constraints;
392-
393-
let region_obligations = region_outlives.iter().map(move |(r1, r2)| {
394-
let r1 = substitute_value(self.tcx, result_subst, r1);
395-
let r2 = substitute_value(self.tcx, result_subst, r2);
396-
Obligation::new(
397-
cause.clone(),
398-
param_env,
399-
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))),
400-
)
401-
});
402-
403-
let ty_obligations = ty_outlives.iter().map(move |(t1, r2)| {
404-
let t1 = substitute_value(self.tcx, result_subst, t1);
381+
) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a {
382+
Box::new(unsubstituted_region_constraints.iter().map(move |constraint| {
383+
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
384+
let k1 = substitute_value(self.tcx, result_subst, k1);
405385
let r2 = substitute_value(self.tcx, result_subst, r2);
406-
Obligation::new(
407-
cause.clone(),
408-
param_env,
409-
ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
410-
)
411-
});
412-
413-
region_obligations.chain(ty_obligations)
386+
match k1.unpack() {
387+
UnpackedKind::Lifetime(r1) =>
388+
Obligation::new(
389+
cause.clone(),
390+
param_env,
391+
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))),
392+
),
393+
394+
UnpackedKind::Type(t1) =>
395+
Obligation::new(
396+
cause.clone(),
397+
param_env,
398+
ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
399+
),
400+
}
401+
})) as Box<dyn Iterator<Item = _>>
414402
}
415403

416404
/// Given two sets of values for the same set of canonical variables, unify them.
@@ -913,19 +901,6 @@ BraceStructTypeFoldableImpl! {
913901
}
914902
}
915903

916-
BraceStructTypeFoldableImpl! {
917-
impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
918-
region_outlives, ty_outlives
919-
}
920-
}
921-
922-
BraceStructLiftImpl! {
923-
impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
924-
type Lifted = QueryRegionConstraints<'tcx>;
925-
region_outlives, ty_outlives
926-
}
927-
}
928-
929904
BraceStructTypeFoldableImpl! {
930905
impl<'tcx, R> TypeFoldable<'tcx> for QueryResult<'tcx, R> {
931906
var_values, region_constraints, certainty, value

src/librustc_traits/util.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
// except according to those terms.
1010

1111
use rustc::infer::InferCtxt;
12-
use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraints,
13-
QueryResult};
12+
use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryResult};
1413
use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
1514
use rustc::traits::{FulfillmentContext, TraitEngine};
1615
use rustc::traits::query::NoSolution;
@@ -62,7 +61,7 @@ where
6261

6362
let region_obligations = infcx.take_registered_region_obligations();
6463

65-
let (region_outlives, ty_outlives) = infcx.with_region_constraints(|region_constraints| {
64+
let region_constraints = infcx.with_region_constraints(|region_constraints| {
6665
let RegionConstraintData {
6766
constraints,
6867
verifys,
@@ -72,24 +71,32 @@ where
7271
assert!(verifys.is_empty());
7372
assert!(givens.is_empty());
7473

75-
let region_outlives: Vec<_> = constraints
74+
let mut outlives: Vec<_> = constraints
7675
.into_iter()
7776
.map(|(k, _)| match *k {
78-
Constraint::VarSubVar(v1, v2) => {
79-
(tcx.mk_region(ty::ReVar(v1)), tcx.mk_region(ty::ReVar(v2)))
77+
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
78+
tcx.mk_region(ty::ReVar(v1)).into(),
79+
tcx.mk_region(ty::ReVar(v2)),
80+
),
81+
Constraint::VarSubReg(v1, r2) => {
82+
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v1)).into(), r2)
8083
}
81-
Constraint::VarSubReg(v1, r2) => (tcx.mk_region(ty::ReVar(v1)), r2),
82-
Constraint::RegSubVar(r1, v2) => (r1, tcx.mk_region(ty::ReVar(v2))),
83-
Constraint::RegSubReg(r1, r2) => (r1, r2),
84+
Constraint::RegSubVar(r1, v2) => {
85+
ty::OutlivesPredicate(r1.into(), tcx.mk_region(ty::ReVar(v2)))
86+
}
87+
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r1.into(), r2),
8488
})
89+
.map(ty::Binder) // no bound regions in the code above
8590
.collect();
8691

87-
let ty_outlives: Vec<_> = region_obligations
88-
.into_iter()
89-
.map(|(_, r_o)| (r_o.sup_type, r_o.sub_region))
90-
.collect();
92+
outlives.extend(
93+
region_obligations
94+
.into_iter()
95+
.map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
96+
.map(ty::Binder) // no bound regions in the code above
97+
);
9198

92-
(region_outlives, ty_outlives)
99+
outlives
93100
});
94101

95102
let certainty = if ambig_errors.is_empty() {
@@ -100,10 +107,7 @@ where
100107

101108
let (canonical_result, _) = infcx.canonicalize_response(&QueryResult {
102109
var_values: inference_vars,
103-
region_constraints: QueryRegionConstraints {
104-
region_outlives,
105-
ty_outlives,
106-
},
110+
region_constraints,
107111
certainty,
108112
value: answer,
109113
});

0 commit comments

Comments
 (0)