about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2023-05-05 12:46:27 +0900
committerGitHub <noreply@github.com>2023-05-05 12:46:27 +0900
commitf5c50e3350baaea9594196a5b7f07ec1db8445bf (patch)
treed3b2ec0441305b284ee667ff0bbdb520eb9c4822
parentb2ee088c73158be66b643ace58857a842d38add8 (diff)
parent0c5fe37786425edf53db60f20fe68f86dcb0b481 (diff)
downloadrust-f5c50e3350baaea9594196a5b7f07ec1db8445bf.tar.gz
rust-f5c50e3350baaea9594196a5b7f07ec1db8445bf.zip
Rollup merge of #111132 - lcnr:nll-generalize, r=b-naber
cleanup nll generalizer

followup to #108861
-rw-r--r--compiler/rustc_borrowck/src/lib.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs13
-rw-r--r--compiler/rustc_infer/src/infer/at.rs3
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs32
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs75
6 files changed, 20 insertions, 113 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index c4c54620e04..315303b25fe 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -498,11 +498,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
         let next_region = self.infcx.next_region_var(origin);
         let vid = next_region.as_var();
 
-        if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
             let ctxt = get_ctxt_fn();
             let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(vid, ctxt);
+            assert_eq!(var_to_origin.insert(vid, ctxt), None);
         }
 
         next_region
@@ -520,11 +520,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
         let next_region = self.infcx.next_nll_region_var(origin);
         let vid = next_region.as_var();
 
-        if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
             let ctxt = get_ctxt_fn();
             let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(vid, ctxt);
+            assert_eq!(var_to_origin.insert(vid, ctxt), None);
         }
 
         next_region
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 7e6d17ec343..7158c62b548 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -131,9 +131,13 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
         };
 
-        if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(reg.as_var(), RegionCtxt::Placeholder(reg_info));
+            let new = RegionCtxt::Placeholder(reg_info);
+            let prev = var_to_origin.insert(reg.as_var(), new);
+            if let Some(prev) = prev {
+                assert_eq!(new, prev);
+            }
         }
 
         reg
@@ -146,9 +150,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             universe,
         );
 
-        if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None));
+            let prev = var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None));
+            assert_eq!(prev, None);
         }
 
         reg
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index d240d8e491f..0c8854e962a 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -30,8 +30,6 @@ use super::*;
 use rustc_middle::ty::relate::{Relate, TypeRelation};
 use rustc_middle::ty::{Const, ImplSubject};
 
-use std::cell::Cell;
-
 /// Whether we should define opaque types or just treat them opaquely.
 ///
 /// Currently only used to prevent predicate matching from matching anything
@@ -84,7 +82,6 @@ impl<'tcx> InferCtxt<'tcx> {
             in_snapshot: self.in_snapshot.clone(),
             universe: self.universe.clone(),
             intercrate: self.intercrate,
-            inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index d798202a644..427d05c8b4d 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -561,8 +561,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
-        let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();
-
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::HAS_INFER |
             TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1cfdb791cd6..a89b9931599 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -39,7 +39,6 @@ use rustc_span::Span;
 
 use std::cell::{Cell, RefCell};
 use std::fmt;
-use std::ops::Drop;
 
 use self::combine::CombineFields;
 use self::error_reporting::TypeErrCtxt;
@@ -342,11 +341,6 @@ pub struct InferCtxt<'tcx> {
     /// there is no type that the user could *actually name* that
     /// would satisfy it. This avoids crippling inference, basically.
     pub intercrate: bool,
-
-    /// Flag that is set when we enter canonicalization. Used for debugging to ensure
-    /// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin`
-    /// inside non-canonicalization contexts.
-    inside_canonicalization_ctxt: Cell<bool>,
 }
 
 /// See the `error_reporting` module for more details.
@@ -638,7 +632,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             skip_leak_check: Cell::new(false),
             universe: Cell::new(ty::UniverseIndex::ROOT),
             intercrate,
-            inside_canonicalization_ctxt: Cell::new(false),
         }
     }
 }
@@ -1636,31 +1629,6 @@ impl<'tcx> InferCtxt<'tcx> {
             }
         }
     }
-
-    pub fn inside_canonicalization_ctxt(&self) -> bool {
-        self.inside_canonicalization_ctxt.get()
-    }
-
-    pub fn set_canonicalization_ctxt(&self) -> CanonicalizationCtxtGuard<'_, 'tcx> {
-        let prev_ctxt = self.inside_canonicalization_ctxt();
-        self.inside_canonicalization_ctxt.set(true);
-        CanonicalizationCtxtGuard { prev_ctxt, infcx: self }
-    }
-
-    fn set_canonicalization_ctxt_to(&self, ctxt: bool) {
-        self.inside_canonicalization_ctxt.set(ctxt);
-    }
-}
-
-pub struct CanonicalizationCtxtGuard<'cx, 'tcx> {
-    prev_ctxt: bool,
-    infcx: &'cx InferCtxt<'tcx>,
-}
-
-impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> {
-    fn drop(&mut self) {
-        self.infcx.set_canonicalization_ctxt_to(self.prev_ctxt)
-    }
 }
 
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 9f7b26b87f4..88a0a81e276 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -30,11 +30,10 @@ use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
 use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
-use std::ops::ControlFlow;
 
 use super::combine::ObligationEmittingRelation;
 
@@ -115,11 +114,6 @@ pub trait TypeRelatingDelegate<'tcx> {
     fn forbid_inference_vars() -> bool;
 }
 
-#[derive(Clone, Debug, Default)]
-struct BoundRegionScope<'tcx> {
-    map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
-}
-
 #[derive(Copy, Clone)]
 struct UniversallyQuantified(bool);
 
@@ -230,10 +224,13 @@ where
     ) -> RelateResult<'tcx, T> {
         let universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
 
+        if value.has_escaping_bound_vars() {
+            bug!("trying to instantiate {for_vid:?} with escaping bound vars: {value:?}");
+        }
+
         let mut generalizer = TypeGeneralizer {
             infcx: self.infcx,
             delegate: &mut self.delegate,
-            first_free_index: ty::INNERMOST,
             ambient_variance: self.ambient_variance,
             for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid),
             universe,
@@ -488,13 +485,7 @@ where
         }
 
         if a == b {
-            // Subtle: if a or b has a bound variable that we are lazily
-            // substituting, then even if a == b, it could be that the values we
-            // will substitute for those bound variables are *not* the same, and
-            // hence returning `Ok(a)` is incorrect.
-            if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
-                return Ok(a);
-            }
+            return Ok(a);
         }
 
         match (a.kind(), b.kind()) {
@@ -726,47 +717,6 @@ where
     }
 }
 
-/// When we encounter a binder like `for<..> fn(..)`, we actually have
-/// to walk the `fn` value to find all the values bound by the `for`
-/// (these are not explicitly present in the ty representation right
-/// now). This visitor handles that: it descends the type, tracking
-/// binder depth, and finds late-bound regions targeting the
-/// `for<..`>. For each of those, it creates an entry in
-/// `bound_region_scope`.
-struct ScopeInstantiator<'me, 'tcx> {
-    next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-    // The debruijn index of the scope we are instantiating.
-    target_index: ty::DebruijnIndex,
-    bound_region_scope: &'me mut BoundRegionScope<'tcx>,
-}
-
-impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> ControlFlow<Self::BreakTy> {
-        self.target_index.shift_in(1);
-        t.super_visit_with(self);
-        self.target_index.shift_out(1);
-
-        ControlFlow::Continue(())
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
-        let ScopeInstantiator { bound_region_scope, next_region, .. } = self;
-
-        match *r {
-            ty::ReLateBound(debruijn, br) if debruijn == self.target_index => {
-                bound_region_scope.map.entry(br).or_insert_with(|| next_region(br));
-            }
-
-            _ => {}
-        }
-
-        ControlFlow::Continue(())
-    }
-}
-
 /// The "type generalizer" is used when handling inference variables.
 ///
 /// The basic strategy for handling a constraint like `?A <: B` is to
@@ -780,11 +730,6 @@ impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
 /// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
 /// establishes `'0: 'x` as a constraint.
 ///
-/// As a side-effect of this generalization procedure, we also replace
-/// all the bound regions that we have traversed with concrete values,
-/// so that the resulting generalized type is independent from the
-/// scopes.
-///
 /// [blog post]: https://is.gd/0hKvIr
 struct TypeGeneralizer<'me, 'tcx, D>
 where
@@ -798,8 +743,6 @@ where
     /// some other type. What will be the variance at this point?
     ambient_variance: ty::Variance,
 
-    first_free_index: ty::DebruijnIndex,
-
     /// The vid of the type variable that is in the process of being
     /// instantiated. If we find this within the value we are folding,
     /// that means we would have created a cyclic value.
@@ -939,7 +882,7 @@ where
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("TypeGeneralizer::regions(a={:?})", a);
 
-        if let ty::ReLateBound(debruijn, _) = *a && debruijn < self.first_free_index {
+        if let ty::ReLateBound(..) = *a {
             return Ok(a);
         }
 
@@ -958,7 +901,6 @@ where
         // FIXME(#54105) -- if the ambient variance is bivariant,
         // though, we may however need to check well-formedness or
         // risk a problem like #41677 again.
-
         let replacement_region_vid = self.delegate.generalize_existential(self.universe);
 
         Ok(replacement_region_vid)
@@ -1002,10 +944,7 @@ where
         T: Relate<'tcx>,
     {
         debug!("TypeGeneralizer::binders(a={:?})", a);
-
-        self.first_free_index.shift_in(1);
         let result = self.relate(a.skip_binder(), a.skip_binder())?;
-        self.first_free_index.shift_out(1);
         Ok(a.rebind(result))
     }
 }