about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/handle_placeholders.rs10
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs20
2 files changed, 18 insertions, 12 deletions
diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs
index 94379cdebf7..6be90994015 100644
--- a/compiler/rustc_borrowck/src/handle_placeholders.rs
+++ b/compiler/rustc_borrowck/src/handle_placeholders.rs
@@ -166,13 +166,9 @@ impl RegionTracker {
         }
     }
 
-    /// Determine if the tracked universes of the two SCCs are compatible.
-    pub(crate) fn universe_compatible_with(&self, other: Self) -> bool {
-        // HACK: We first check whether we can name the highest existential universe
-        // of `other`. This only exists to avoid errors in case that scc already
-        // depends on a placeholder it cannot name itself.
-        self.max_nameable_universe().can_name(other.max_nameable_universe())
-            || other.reachable_placeholders.can_be_named_by(self.max_nameable_universe())
+    /// Determine if we can name all the placeholders in `other`.
+    pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool {
+        other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0)
     }
 
     /// If this SCC reaches a placeholder it can't name, return it.
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index f57456949bb..5f4bfd9df48 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -571,11 +571,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
     }
 
-    /// Returns `true` if all the elements in the value of `scc_b` are nameable
+    /// Returns `true` if all the placeholders in the value of `scc_b` are nameable
     /// in `scc_a`. Used during constraint propagation, and only once
     /// the value of `scc_b` has been computed.
-    fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool {
-        self.scc_annotations[scc_a].universe_compatible_with(self.scc_annotations[scc_b])
+    fn can_name_all_placeholders(
+        &self,
+        scc_a: ConstraintSccIndex,
+        scc_b: ConstraintSccIndex,
+    ) -> bool {
+        self.scc_annotations[scc_a].can_name_all_placeholders(self.scc_annotations[scc_b])
     }
 
     /// Once regions have been propagated, this method is used to see
@@ -964,16 +968,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             return true;
         }
 
+        let fr_static = self.universal_regions().fr_static;
+
         // If we are checking that `'sup: 'sub`, and `'sub` contains
         // some placeholder that `'sup` cannot name, then this is only
         // true if `'sup` outlives static.
-        if !self.universe_compatible(sub_region_scc, sup_region_scc) {
+        //
+        // Avoid infinite recursion if `sub_region` is already `'static`
+        if sub_region != fr_static
+            && !self.can_name_all_placeholders(sup_region_scc, sub_region_scc)
+        {
             debug!(
                 "sub universe `{sub_region_scc:?}` is not nameable \
                 by super `{sup_region_scc:?}`, promoting to static",
             );
 
-            return self.eval_outlives(sup_region, self.universal_regions().fr_static);
+            return self.eval_outlives(sup_region, fr_static);
         }
 
         // Both the `sub_region` and `sup_region` consist of the union