about summary refs log tree commit diff
path: root/compiler/rustc_infer/src
diff options
context:
space:
mode:
authorBoxy <supbscripter@gmail.com>2024-02-08 13:19:20 +0000
committerBoxy <supbscripter@gmail.com>2024-02-08 13:19:25 +0000
commitf867742be8a19ca253b0d7d1c9a4ab54b7ff02c5 (patch)
treee22b6b50d8d00d2319aeeca635e6d727dd7d0cc8 /compiler/rustc_infer/src
parentb181a1262326795a438e0d9118fd71b7bc94c3ae (diff)
downloadrust-f867742be8a19ca253b0d7d1c9a4ab54b7ff02c5.tar.gz
rust-f867742be8a19ca253b0d7d1c9a4ab54b7ff02c5.zip
reviews + rebase
Diffstat (limited to 'compiler/rustc_infer/src')
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs15
-rw-r--r--compiler/rustc_infer/src/infer/relate/nll.rs89
3 files changed, 49 insertions, 57 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index f7969e31dee..2d87f01ff10 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1032,7 +1032,6 @@ impl<'tcx> InferCtxt<'tcx> {
             _ => {}
         }
 
-        // FIXME(tree_universes): leaking placeholders
         self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
             Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
         })
@@ -1043,7 +1042,6 @@ impl<'tcx> InferCtxt<'tcx> {
         cause: &traits::ObligationCause<'tcx>,
         predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
     ) {
-        // FIXME(tree_universes): leaking placeholders
         self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
             let origin = SubregionOrigin::from_obligation_cause(cause, || {
                 RelateRegionParamBound(cause.span)
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index ff01f620e66..90be80f67b4 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -49,7 +49,6 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
             debug!("b_prime={:?}", sup_prime);
 
             // Compare types now that bound regions have been replaced.
-            // FIXME(tree_universes): leaked universes
             let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
             if result.is_ok() {
                 debug!("OK result={result:?}");
@@ -70,7 +69,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// This is the first step of checking subtyping when higher-ranked things are involved.
     /// For more details visit the relevant sections of the [rustc dev guide].
     ///
-    /// `enter_forall` should be preferred over this method.
+    /// `fn enter_forall` should be preferred over this method.
     ///
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
     #[instrument(level = "debug", skip(self), ret)]
@@ -111,14 +110,14 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     /// Replaces all bound variables (lifetimes, types, and constants) bound by
-    /// `binder` with placeholder variables in a new universe. This means that the
-    /// new placeholders can only be named by inference variables created after
-    /// this method has been called.
+    /// `binder` with placeholder variables in a new universe and then calls the
+    /// closure `f` with the instantiated value. The new placeholders can only be
+    /// named by inference variables created inside of the closure `f` or afterwards.
     ///
     /// This is the first step of checking subtyping when higher-ranked things are involved.
     /// For more details visit the relevant sections of the [rustc dev guide].
     ///
-    /// This method should be preferred over `enter_forall_and_leak_universe`.
+    /// This method should be preferred over `fn enter_forall_and_leak_universe`.
     ///
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
     #[instrument(level = "debug", skip(self, f))]
@@ -126,6 +125,10 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
+        // FIXME: currently we do nothing to prevent placeholders with the new universe being
+        // used after exiting `f`. For example region subtyping can result in outlives constraints
+        // that name placeholders created in this function. Nested goals from type relations can
+        // also contain placeholders created by this function.
         let value = self.enter_forall_and_leak_universe(forall);
         debug!("?value");
         f(value)
diff --git a/compiler/rustc_infer/src/infer/relate/nll.rs b/compiler/rustc_infer/src/infer/relate/nll.rs
index 2760356bcdf..5e2d2af9b85 100644
--- a/compiler/rustc_infer/src/infer/relate/nll.rs
+++ b/compiler/rustc_infer/src/infer/relate/nll.rs
@@ -261,54 +261,6 @@ where
         Ok(a)
     }
 
-    #[instrument(skip(self), level = "debug")]
-    fn enter_forall_and_leak_universe<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T
-    where
-        T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
-    {
-        if let Some(inner) = binder.no_bound_vars() {
-            return inner;
-        }
-
-        let mut next_region = {
-            let nll_delegate = &mut self.delegate;
-            let mut lazy_universe = None;
-
-            move |br: ty::BoundRegion| {
-                // The first time this closure is called, create a
-                // new universe for the placeholders we will make
-                // from here out.
-                let universe = lazy_universe.unwrap_or_else(|| {
-                    let universe = nll_delegate.create_next_universe();
-                    lazy_universe = Some(universe);
-                    universe
-                });
-
-                let placeholder = ty::PlaceholderRegion { universe, bound: br };
-                debug!(?placeholder);
-                let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
-                debug!(?placeholder_reg);
-
-                placeholder_reg
-            }
-        };
-
-        let delegate = FnMutDelegate {
-            regions: &mut next_region,
-            types: &mut |_bound_ty: ty::BoundTy| {
-                unreachable!("we only replace regions in nll_relate, not types")
-            },
-            consts: &mut |_bound_var: ty::BoundVar, _ty| {
-                unreachable!("we only replace regions in nll_relate, not consts")
-            },
-        };
-
-        let replaced = self.infcx.tcx.replace_bound_vars_uncached(binder, delegate);
-        debug!(?replaced);
-
-        replaced
-    }
-
     fn enter_forall<T, U>(
         &mut self,
         binder: ty::Binder<'tcx, T>,
@@ -317,7 +269,46 @@ where
     where
         T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
-        let value = self.enter_forall_and_leak_universe(binder);
+        let value = if let Some(inner) = binder.no_bound_vars() {
+            inner
+        } else {
+            let mut next_region = {
+                let nll_delegate = &mut self.delegate;
+                let mut lazy_universe = None;
+
+                move |br: ty::BoundRegion| {
+                    // The first time this closure is called, create a
+                    // new universe for the placeholders we will make
+                    // from here out.
+                    let universe = lazy_universe.unwrap_or_else(|| {
+                        let universe = nll_delegate.create_next_universe();
+                        lazy_universe = Some(universe);
+                        universe
+                    });
+
+                    let placeholder = ty::PlaceholderRegion { universe, bound: br };
+                    debug!(?placeholder);
+                    let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
+                    debug!(?placeholder_reg);
+
+                    placeholder_reg
+                }
+            };
+
+            let delegate = FnMutDelegate {
+                regions: &mut next_region,
+                types: &mut |_bound_ty: ty::BoundTy| {
+                    unreachable!("we only replace regions in nll_relate, not types")
+                },
+                consts: &mut |_bound_var: ty::BoundVar, _ty| {
+                    unreachable!("we only replace regions in nll_relate, not consts")
+                },
+            };
+
+            self.infcx.tcx.replace_bound_vars_uncached(binder, delegate)
+        };
+
+        debug!(?value);
         f(self, value)
     }