summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/canonical
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/canonical')
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs13
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs74
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs7
3 files changed, 51 insertions, 43 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index ca7862c9d..9488d0a6c 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -180,11 +180,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match *r {
- ty::ReFree(_)
- | ty::ReErased
- | ty::ReStatic
- | ty::ReEmpty(ty::UniverseIndex::ROOT)
- | ty::ReEarlyBound(..) => r,
+ ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r,
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
@@ -199,10 +195,6 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
)
}
- ty::ReEmpty(ui) => {
- bug!("canonicalizing 'empty in universe {:?}", ui) // FIXME
- }
-
_ => {
// Other than `'static` or `'empty`, the query
// response should be executing in a fully
@@ -372,7 +364,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
debug!(
"canonical: region var found with vid {:?}, \
opportunistically resolved to {:?}",
- vid, r
+ vid, resolved_vid
);
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
self.canonicalize_mode.canonicalize_free_region(self, r)
@@ -381,7 +373,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReFree(_)
- | ty::ReEmpty(_)
| ty::RePlaceholder(..)
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
}
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 8dc20544f..56e834898 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -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;
@@ -63,8 +64,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
{
let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
+ debug!("query_response = {:#?}", query_response);
let canonical_result = self.canonicalize_response(query_response);
-
debug!("canonical_result = {:#?}", canonical_result);
Ok(self.tcx.arena.alloc(canonical_result))
@@ -125,13 +126,17 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
debug!("ambig_errors = {:#?}", ambig_errors);
let region_obligations = self.take_registered_region_obligations();
+ debug!(?region_obligations);
let region_constraints = self.with_region_constraints(|region_constraints| {
make_query_region_constraints(
tcx,
- region_obligations.iter().map(|r_o| (r_o.sup_type, r_o.sub_region)),
+ region_obligations
+ .iter()
+ .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
region_constraints,
)
});
+ debug!(?region_constraints);
let certainty =
if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous };
@@ -246,6 +251,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// the original values `v_o` that was canonicalized into a
// variable...
+ let constraint_category = cause.to_constraint_category();
+
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| {
@@ -261,12 +268,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,
+ ));
}
}
@@ -312,7 +321,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 }
}),
);
@@ -557,7 +566,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) => {
@@ -572,7 +581,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)
}
@@ -623,7 +632,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// creates query region constraints.
pub fn make_query_region_constraints<'tcx>(
tcx: TyCtxt<'tcx>,
- outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>)>,
+ outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
region_constraints: &RegionConstraintData<'tcx>,
) -> QueryRegionConstraints<'tcx> {
let RegionConstraintData { constraints, verifys, givens, member_constraints } =
@@ -632,28 +641,35 @@ pub fn make_query_region_constraints<'tcx>(
assert!(verifys.is_empty());
assert!(givens.is_empty());
+ debug!(?constraints);
+
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, origin)| {
+ // no bound vars in the code above
+ 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, origin.to_constraint_category())
})
- .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, constraint_category)| {
+ (ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)), constraint_category)
+ }),
)
.collect();
diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs
index 34b611342..389afe22e 100644
--- a/compiler/rustc_infer/src/infer/canonical/substitute.rs
+++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs
@@ -72,15 +72,16 @@ where
value
} else {
let delegate = FnMutDelegate {
- regions: |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
+ regions: &mut |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
GenericArgKind::Lifetime(l) => l,
r => bug!("{:?} is a region but value is {:?}", br, r),
},
- types: |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() {
+ types: &mut |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() {
GenericArgKind::Type(ty) => ty,
r => bug!("{:?} is a type but value is {:?}", bound_ty, r),
},
- consts: |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack() {
+ consts: &mut |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack()
+ {
GenericArgKind::Const(ct) => ct,
c => bug!("{:?} is a const but value is {:?}", bound_ct, c),
},