about summary refs log tree commit diff
path: root/compiler/rustc_infer/src/infer
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-05-04 20:40:02 +0000
committerMichael Goulet <michael@errs.io>2023-05-15 16:40:42 +0000
commitc270b0a8a844f0bac1ee1acd8a1ebabc0cee65e7 (patch)
treed5e2d8f81675c1fdf38b52ea47d6e309c40396c9 /compiler/rustc_infer/src/infer
parent338e7642fbe6af32351363ab1044494da14b0dec (diff)
downloadrust-c270b0a8a844f0bac1ee1acd8a1ebabc0cee65e7.tar.gz
rust-c270b0a8a844f0bac1ee1acd8a1ebabc0cee65e7.zip
Simplify delegate
Diffstat (limited to 'compiler/rustc_infer/src/infer')
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs30
-rw-r--r--compiler/rustc_infer/src/infer/generalize.rs82
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs27
3 files changed, 70 insertions, 69 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index a5d7641504d..b13c9627bf7 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -28,7 +28,7 @@ use super::lub::Lub;
 use super::sub::Sub;
 use super::type_variable::TypeVariableValue;
 use super::{DefineOpaqueTypes, InferCtxt, MiscVariable, TypeTrace};
-use crate::infer::generalize::{Generalization, Generalizer};
+use crate::infer::generalize::{generalize, CombineDelegate, Generalization};
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::infer::canonical::OriginalQueryValues;
 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
@@ -471,25 +471,17 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
             RelationDir::SupertypeOf => ty::Contravariant,
         };
 
-        trace!(?ambient_variance);
-
-        let for_universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
-        let for_vid_sub_root = self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid);
-
-        trace!(?for_universe);
-        trace!(?self.trace);
-
-        Generalizer {
-            infcx: self.infcx,
-            delegate: self,
+        generalize::generalize(
+            self.infcx,
+            &mut CombineDelegate {
+                infcx: self.infcx,
+                param_env: self.param_env,
+                span: self.trace.span(),
+            },
+            ty,
+            for_vid,
             ambient_variance,
-            for_universe,
-            for_vid_sub_root,
-            root_ty: ty,
-            cache: Default::default(),
-            needs_wf: false,
-        }
-        .generalize(ty)
+        )
     }
 
     pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
index 8913f5c8a43..c8562c84a17 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -4,12 +4,41 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt};
+use rustc_span::Span;
 
-use crate::infer::combine::CombineFields;
 use crate::infer::nll_relate::TypeRelatingDelegate;
 use crate::infer::type_variable::TypeVariableValue;
 use crate::infer::{InferCtxt, RegionVariableOrigin};
 
+pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>>(
+    infcx: &InferCtxt<'tcx>,
+    delegate: &mut D,
+    ty: Ty<'tcx>,
+    for_vid: ty::TyVid,
+    ambient_variance: ty::Variance,
+) -> RelateResult<'tcx, Generalization<Ty<'tcx>>> {
+    let for_universe = infcx.probe_ty_var(for_vid).unwrap_err();
+    let for_vid_sub_root = infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid);
+
+    let mut generalizer = Generalizer {
+        infcx,
+        delegate,
+        ambient_variance,
+        for_vid_sub_root,
+        for_universe,
+        root_ty: ty,
+        needs_wf: false,
+        cache: Default::default(),
+    };
+
+    assert!(!ty.has_escaping_bound_vars());
+    let value = generalizer.relate(ty, ty)?;
+    let needs_wf = generalizer.needs_wf;
+    Ok(Generalization { value, needs_wf })
+}
+
+/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
+/// in the generalizer code.
 pub trait GeneralizerDelegate<'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
 
@@ -18,7 +47,13 @@ pub trait GeneralizerDelegate<'tcx> {
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
 }
 
-impl<'tcx> GeneralizerDelegate<'tcx> for CombineFields<'_, 'tcx> {
+pub struct CombineDelegate<'cx, 'tcx> {
+    pub infcx: &'cx InferCtxt<'tcx>,
+    pub param_env: ty::ParamEnv<'tcx>,
+    pub span: Span,
+}
+
+impl<'tcx> GeneralizerDelegate<'tcx> for CombineDelegate<'_, 'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.param_env
     }
@@ -28,10 +63,8 @@ impl<'tcx> GeneralizerDelegate<'tcx> for CombineFields<'_, 'tcx> {
     }
 
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
-        self.infcx.next_region_var_in_universe(
-            RegionVariableOrigin::MiscVariable(self.trace.span()),
-            universe,
-        )
+        self.infcx
+            .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(self.span), universe)
     }
 }
 
@@ -66,7 +99,7 @@ where
 /// establishes `'0: 'x` as a constraint.
 ///
 /// [blog post]: https://is.gd/0hKvIr
-pub(super) struct Generalizer<'me, 'tcx, D>
+struct Generalizer<'me, 'tcx, D>
 where
     D: GeneralizerDelegate<'tcx>,
 {
@@ -98,18 +131,6 @@ where
     needs_wf: bool,
 }
 
-impl<'tcx, D: GeneralizerDelegate<'tcx>> Generalizer<'_, 'tcx, D> {
-    pub fn generalize<T>(mut self, value: T) -> RelateResult<'tcx, Generalization<T>>
-    where
-        T: Relate<'tcx>,
-    {
-        assert!(!value.has_escaping_bound_vars());
-        let value = self.relate(value, value)?;
-        let needs_wf = self.needs_wf;
-        Ok(Generalization { value, needs_wf })
-    }
-}
-
 impl<'tcx, D> TypeRelation<'tcx> for Generalizer<'_, 'tcx, D>
 where
     D: GeneralizerDelegate<'tcx>,
@@ -202,17 +223,19 @@ where
             }
 
             ty::Infer(ty::TyVar(vid)) => {
-                let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
-                let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid);
+                let mut inner = self.infcx.inner.borrow_mut();
+                let vid = inner.type_variables().root_var(vid);
+                let sub_vid = inner.type_variables().sub_root_var(vid);
                 if sub_vid == self.for_vid_sub_root {
                     // If sub-roots are equal, then `for_vid` and
                     // `vid` are related via subtyping.
                     Err(TypeError::CyclicTy(self.root_ty))
                 } else {
-                    let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid);
+                    let probe = inner.type_variables().probe(vid);
                     match probe {
                         TypeVariableValue::Known { value: u } => {
                             debug!("generalize: known value {:?}", u);
+                            drop(inner);
                             self.relate(u, u)
                         }
                         TypeVariableValue::Unknown { universe } => {
@@ -235,20 +258,15 @@ where
                                 ty::Covariant | ty::Contravariant => (),
                             }
 
-                            let origin =
-                                *self.infcx.inner.borrow_mut().type_variables().var_origin(vid);
-                            let new_var_id = self
-                                .infcx
-                                .inner
-                                .borrow_mut()
-                                .type_variables()
-                                .new_var(self.for_universe, origin);
+                            let origin = *inner.type_variables().var_origin(vid);
+                            let new_var_id =
+                                inner.type_variables().new_var(self.for_universe, origin);
                             let u = self.tcx().mk_ty_var(new_var_id);
 
                             // Record that we replaced `vid` with `new_var_id` as part of a generalization
                             // operation. This is needed to detect cyclic types. To see why, see the
                             // docs in the `type_variables` module.
-                            self.infcx.inner.borrow_mut().type_variables().sub(vid, new_var_id);
+                            inner.type_variables().sub(vid, new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
                             Ok(u)
                         }
@@ -278,7 +296,7 @@ where
 
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
                 let s = self.relate(substs, substs)?;
-                Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) })
+                Ok(if s == substs { t } else { self.tcx().mk_opaque(def_id, s) })
             }
             _ => relate::super_relate_tys(self, t, t),
         }?;
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index f479dbdc43c..4ae6af5f5be 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -31,7 +31,7 @@ use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
 
 use crate::infer::combine::ObligationEmittingRelation;
-use crate::infer::generalize::{Generalization, Generalizer};
+use crate::infer::generalize::{self, Generalization};
 use crate::infer::InferCtxt;
 use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::traits::{Obligation, PredicateObligations};
@@ -217,23 +217,14 @@ where
     }
 
     fn generalize(&mut self, ty: Ty<'tcx>, for_vid: ty::TyVid) -> RelateResult<'tcx, Ty<'tcx>> {
-        let for_universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
-        let for_vid_sub_root = self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid);
-
-        // FIXME: we may need a WF predicate (related to #54105).
-        let Generalization { value, needs_wf: _ } = Generalizer {
-            infcx: self.infcx,
-            delegate: &mut self.delegate,
-            ambient_variance: self.ambient_variance,
-            for_vid_sub_root,
-            for_universe,
-            root_ty: ty,
-            needs_wf: false,
-            cache: Default::default(),
-        }
-        .generalize(ty)?;
-
-        Ok(value)
+        let Generalization { value: ty, needs_wf: _ } = generalize::generalize(
+            self.infcx,
+            &mut self.delegate,
+            ty,
+            for_vid,
+            self.ambient_variance,
+        )?;
+        Ok(ty)
     }
 
     fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {