1
Fork 0

Don't hang when there's an infinite loop of outlives obligations

This commit is contained in:
Michael Goulet 2024-02-01 18:04:16 +00:00
parent 7d1fda7b40
commit a371059933
2 changed files with 87 additions and 62 deletions

View file

@ -154,9 +154,19 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
} = *self; } = *self;
let mut outlives_predicates = vec![(predicate, constraint_category)]; let mut outlives_predicates = vec![(predicate, constraint_category)];
while let Some((ty::OutlivesPredicate(k1, r2), constraint_category)) = for iteration in 0.. {
outlives_predicates.pop() if outlives_predicates.is_empty() {
{ break;
}
if !self.tcx.recursion_limit().value_within_limit(iteration) {
bug!(
"FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}"
);
}
let mut next_outlives_predicates = vec![];
for (ty::OutlivesPredicate(k1, r2), constraint_category) in outlives_predicates {
match k1.unpack() { match k1.unpack() {
GenericArgKind::Lifetime(r1) => { GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(r1); let r1_vid = self.to_region_vid(r1);
@ -196,9 +206,10 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
if let Some(constraints) = constraints { if let Some(constraints) = constraints {
assert!( assert!(
constraints.member_constraints.is_empty(), constraints.member_constraints.is_empty(),
"FIXME(-Znext-solver): How do I handle these?" "no member constraints expected from normalizing: {:#?}",
constraints.member_constraints
); );
outlives_predicates next_outlives_predicates
.extend(constraints.outlives.iter().copied()); .extend(constraints.outlives.iter().copied());
} }
} }
@ -217,12 +228,20 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
Some(implicit_region_bound), Some(implicit_region_bound),
known_type_outlives_obligations, known_type_outlives_obligations,
) )
.type_must_outlive(origin, t1, r2, constraint_category); .type_must_outlive(
origin,
t1,
r2,
constraint_category,
);
} }
GenericArgKind::Const(_) => unreachable!(), GenericArgKind::Const(_) => unreachable!(),
} }
} }
outlives_predicates = next_outlives_predicates;
}
} }
/// Placeholder regions need to be converted eagerly because it may /// Placeholder regions need to be converted eagerly because it may

View file

@ -154,12 +154,18 @@ impl<'tcx> InferCtxt<'tcx> {
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?; .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
// Must loop since the process of normalizing may itself register region obligations. // Must loop since the process of normalizing may itself register region obligations.
loop { for iteration in 0.. {
let my_region_obligations = self.take_registered_region_obligations(); let my_region_obligations = self.take_registered_region_obligations();
if my_region_obligations.is_empty() { if my_region_obligations.is_empty() {
break; break;
} }
if !self.tcx.recursion_limit().value_within_limit(iteration) {
bug!(
"FIXME(-Znext-solver): Overflowed when processing region obligations: {my_region_obligations:#?}"
);
}
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations { for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
let sup_type = deeply_normalize_ty(sup_type, origin.clone()) let sup_type = deeply_normalize_ty(sup_type, origin.clone())
.map_err(|e| (e, origin.clone()))?; .map_err(|e| (e, origin.clone()))?;