about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-01-30 21:49:55 +0000
committerMichael Goulet <michael@errs.io>2024-02-02 18:30:21 +0000
commit7576b77e50f2f8a4f256876dd38563e5e5becdee (patch)
tree4f337fe4d5f538c5ae295212329ce27d6dc461e7
parent0e16885abd6997897a28627d1ff514c106261a7f (diff)
downloadrust-7576b77e50f2f8a4f256876dd38563e5e5becdee.tar.gz
rust-7576b77e50f2f8a4f256876dd38563e5e5becdee.zip
Do process_registered_region_obligations in a loop
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs38
1 files changed, 22 insertions, 16 deletions
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index b10bf98e8b5..cf68a60e280 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -153,22 +153,28 @@ impl<'tcx> InferCtxt<'tcx> {
             .try_collect()
             .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
 
-        let my_region_obligations = self.take_registered_region_obligations();
-
-        for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
-            let sup_type =
-                deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?;
-            debug!(?sup_type, ?sub_region, ?origin);
-
-            let outlives = &mut TypeOutlives::new(
-                self,
-                self.tcx,
-                outlives_env.region_bound_pairs(),
-                None,
-                &normalized_caller_bounds,
-            );
-            let category = origin.to_constraint_category();
-            outlives.type_must_outlive(origin, sup_type, sub_region, category);
+        // Must loop since the process of normalizing may itself register region obligations.
+        loop {
+            let my_region_obligations = self.take_registered_region_obligations();
+            if my_region_obligations.is_empty() {
+                break;
+            }
+
+            for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
+                let sup_type = deeply_normalize_ty(sup_type, origin.clone())
+                    .map_err(|e| (e, origin.clone()))?;
+                debug!(?sup_type, ?sub_region, ?origin);
+
+                let outlives = &mut TypeOutlives::new(
+                    self,
+                    self.tcx,
+                    outlives_env.region_bound_pairs(),
+                    None,
+                    &normalized_caller_bounds,
+                );
+                let category = origin.to_constraint_category();
+                outlives.type_must_outlive(origin, sup_type, sub_region, category);
+            }
         }
 
         Ok(())