Make QueryOutlivesConstraint contain a ConstraintCategory

This commit is contained in:
Jack Huey 2022-09-16 16:15:41 -04:00
parent 4d4e51e428
commit a46376e247
6 changed files with 64 additions and 36 deletions

View file

@ -2295,7 +2295,13 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
outlives_requirement={:?}",
region, outlived_region, outlives_requirement,
);
ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region))
(
ty::Binder::dummy(ty::OutlivesPredicate(
region.into(),
outlived_region,
)),
ConstraintCategory::BoringNoLocation,
)
}
ClosureOutlivesSubject::Ty(ty) => {
@ -2305,7 +2311,10 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
outlives_requirement={:?}",
ty, outlived_region, outlives_requirement,
);
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region))
(
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)),
ConstraintCategory::BoringNoLocation,
)
}
}
})

View file

@ -98,9 +98,12 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
// region constraints like `for<'a> 'a: 'b`. At some point
// when we move to universes, we will, and this assertion
// will start to fail.
let ty::OutlivesPredicate(k1, r2) = query_constraint.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", query_constraint,);
});
let ty::OutlivesPredicate(k1, r2) =
query_constraint.0.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", query_constraint,);
});
let _constraint_category = query_constraint.1;
match k1.unpack() {
GenericArgKind::Lifetime(r1) => {

View file

@ -2591,7 +2591,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.enumerate()
.filter_map(|(idx, constraint)| {
let ty::OutlivesPredicate(k1, r2) =
constraint.no_bound_vars().unwrap_or_else(|| {
constraint.0.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", constraint,);
});

View file

@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
@ -248,6 +249,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// the original values `v_o` that was canonicalized into a
// variable...
let constraint_category = ConstraintCategory::BoringNoLocation;
for (index, original_value) in original_values.var_values.iter().enumerate() {
// ...with the value `v_r` of that variable from the query.
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
@ -263,12 +266,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
(GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => {
// To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
if v_o != v_r {
output_query_region_constraints
.outlives
.push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)));
output_query_region_constraints
.outlives
.push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)));
output_query_region_constraints.outlives.push((
ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)),
constraint_category,
));
output_query_region_constraints.outlives.push((
ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)),
constraint_category,
));
}
}
@ -314,7 +319,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// Screen out `'a: 'a` cases -- we skip the binder here but
// 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();
let ty::OutlivesPredicate(k1, r2) = r_c.0.skip_binder();
if k1 != r2.into() { Some(r_c) } else { None }
}),
);
@ -559,7 +564,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Obligation<'tcx, ty::Predicate<'tcx>> {
let ty::OutlivesPredicate(k1, r2) = predicate.skip_binder();
let ty::OutlivesPredicate(k1, r2) = predicate.0.skip_binder();
let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
@ -574,7 +579,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
}
};
let predicate = predicate.rebind(atom).to_predicate(self.tcx);
let predicate = predicate.0.rebind(atom).to_predicate(self.tcx);
Obligation::new(cause, param_env, predicate)
}
@ -638,26 +643,34 @@ pub fn make_query_region_constraints<'tcx>(
let outlives: Vec<_> = constraints
.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(|(k, _)| {
let constraint = ty::Binder::dummy(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),
});
(constraint, ConstraintCategory::BoringNoLocation)
})
.map(ty::Binder::dummy) // no bound vars in the code above
.chain(
outlives_obligations
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
.map(ty::Binder::dummy), // no bound vars in the code above
// no bound vars in the code above
.map(|(ty, r)| {
(
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)),
ConstraintCategory::BoringNoLocation,
)
}),
)
.collect();

View file

@ -22,6 +22,7 @@
//! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
use crate::infer::MemberConstraint;
use crate::mir::ConstraintCategory;
use crate::ty::subst::GenericArg;
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
use rustc_index::vec::IndexVec;
@ -301,8 +302,10 @@ impl<'tcx, V> Canonical<'tcx, V> {
}
}
pub type QueryOutlivesConstraint<'tcx> =
ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
pub type QueryOutlivesConstraint<'tcx> = (
ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>,
ConstraintCategory<'tcx>,
);
TrivialTypeTraversalAndLiftImpls! {
for <'tcx> {

View file

@ -327,7 +327,7 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
///
/// See also `rustc_const_eval::borrow_check::constraints`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[derive(TyEncodable, TyDecodable, HashStable)]
#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)]
pub enum ConstraintCategory<'tcx> {
Return(ReturnConstraint),
Yield,
@ -369,7 +369,7 @@ pub enum ConstraintCategory<'tcx> {
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[derive(TyEncodable, TyDecodable, HashStable)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
pub enum ReturnConstraint {
Normal,
ClosureUpvar(Field),