about summary refs log tree commit diff
path: root/compiler/rustc_infer/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-10-04 12:33:51 -0400
committerMichael Goulet <michael@errs.io>2024-10-10 06:07:51 -0400
commitce7a61b9d0bb4b7bb99ade4bff2449fabc9afd3f (patch)
tree5baec10bdd78d7ddbcc4651ea0de2e4fc732c5a9 /compiler/rustc_infer/src
parent09da2ebd63107997e1319c2a076021660285ef40 (diff)
downloadrust-ce7a61b9d0bb4b7bb99ade4bff2449fabc9afd3f.tar.gz
rust-ce7a61b9d0bb4b7bb99ade4bff2449fabc9afd3f.zip
Uplift super_combine
Diffstat (limited to 'compiler/rustc_infer/src')
-rw-r--r--compiler/rustc_infer/src/infer/context.rs69
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs245
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs1
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs1
6 files changed, 70 insertions, 254 deletions
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
index c06836edcfb..10b22c98a0d 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -1,22 +1,27 @@
 ///! Definition of `InferCtxtLike` from the librarified type layer.
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::solve::{Goal, NoSolution, SolverMode};
 use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
+use rustc_middle::ty::relate::{Relate, RelateResult};
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::DUMMY_SP;
-use rustc_type_ir::InferCtxtLike;
-use rustc_type_ir::relate::Relate;
+use rustc_span::{DUMMY_SP, ErrorGuaranteed};
 
 use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
 
-impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
+impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
     type Interner = TyCtxt<'tcx>;
 
     fn cx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
+    fn next_trait_solver(&self) -> bool {
+        self.next_trait_solver
+    }
+
     fn solver_mode(&self) -> ty::solve::SolverMode {
         match self.intercrate {
             true => SolverMode::Coherence,
@@ -131,6 +136,59 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
         self.enter_forall(value, f)
     }
 
+    fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
+        self.inner.borrow_mut().int_unification_table().union(a, b);
+    }
+
+    fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
+        self.inner.borrow_mut().float_unification_table().union(a, b);
+    }
+
+    fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
+        self.inner.borrow_mut().const_unification_table().union(a, b);
+    }
+
+    fn equate_effect_vids_raw(&self, a: rustc_type_ir::EffectVid, b: rustc_type_ir::EffectVid) {
+        self.inner.borrow_mut().effect_unification_table().union(a, b);
+    }
+
+    fn instantiate_int_var_raw(
+        &self,
+        vid: rustc_type_ir::IntVid,
+        value: rustc_type_ir::IntVarValue,
+    ) {
+        self.inner.borrow_mut().int_unification_table().union_value(vid, value);
+    }
+
+    fn instantiate_float_var_raw(
+        &self,
+        vid: rustc_type_ir::FloatVid,
+        value: rustc_type_ir::FloatVarValue,
+    ) {
+        self.inner.borrow_mut().float_unification_table().union_value(vid, value);
+    }
+
+    fn instantiate_effect_var_raw(&self, vid: rustc_type_ir::EffectVid, value: ty::Const<'tcx>) {
+        self.inner
+            .borrow_mut()
+            .effect_unification_table()
+            .union_value(vid, EffectVarValue::Known(value));
+    }
+
+    fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
+        &self,
+        relation: &mut R,
+        target_is_expected: bool,
+        target_vid: rustc_type_ir::ConstVid,
+        source_ct: ty::Const<'tcx>,
+    ) -> RelateResult<'tcx, ()> {
+        self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
+    }
+
+    fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+        self.set_tainted_by_errors(e)
+    }
+
     fn relate<T: Relate<TyCtxt<'tcx>>>(
         &self,
         param_env: ty::ParamEnv<'tcx>,
@@ -154,6 +212,9 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
     fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.shallow_resolve(ty)
     }
+    fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+        self.shallow_resolve_const(ct)
+    }
 
     fn resolve_vars_if_possible<T>(&self, value: T) -> T
     where
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
deleted file mode 100644
index f879fbc5578..00000000000
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-//! There are four type combiners: `TypeRelating`, `Lub`, and `Glb`,
-//! and `NllTypeRelating` in rustc_borrowck, which is only used for NLL.
-//!
-//! Each implements the trait [TypeRelation] and contains methods for
-//! combining two instances of various things and yielding a new instance.
-//! These combiner methods always yield a `Result<T>`. To relate two
-//! types, you can use `infcx.at(cause, param_env)` which then allows
-//! you to use the relevant methods of [At](crate::infer::at::At).
-//!
-//! Combiners mostly do their specific behavior and then hand off the
-//! bulk of the work to [InferCtxt::super_combine_tys] and
-//! [InferCtxt::super_combine_consts].
-//!
-//! Combining two types may have side-effects on the inference contexts
-//! which can be undone by using snapshots. You probably want to use
-//! either [InferCtxt::commit_if_ok] or [InferCtxt::probe].
-//!
-//! On success, the  LUB/GLB operations return the appropriate bound. The
-//! return value of `Equate` or `Sub` shouldn't really be used.
-
-use rustc_middle::bug;
-use rustc_middle::infer::unify_key::EffectVarValue;
-use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::{self, InferConst, IntType, Ty, TypeVisitableExt, UintType};
-pub use rustc_next_trait_solver::relate::combine::*;
-use tracing::debug;
-
-use super::{RelateResult, StructurallyRelateAliases};
-use crate::infer::{InferCtxt, relate};
-
-impl<'tcx> InferCtxt<'tcx> {
-    pub fn super_combine_tys<R>(
-        &self,
-        relation: &mut R,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-    ) -> RelateResult<'tcx, Ty<'tcx>>
-    where
-        R: PredicateEmittingRelation<InferCtxt<'tcx>>,
-    {
-        debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
-        debug_assert!(!a.has_escaping_bound_vars());
-        debug_assert!(!b.has_escaping_bound_vars());
-
-        match (a.kind(), b.kind()) {
-            (&ty::Error(e), _) | (_, &ty::Error(e)) => {
-                self.set_tainted_by_errors(e);
-                return Ok(Ty::new_error(self.tcx, e));
-            }
-
-            // Relate integral variables to other types
-            (&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => {
-                self.inner.borrow_mut().int_unification_table().union(a_id, b_id);
-                Ok(a)
-            }
-            (&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
-                self.unify_integral_variable(v_id, IntType(v));
-                Ok(b)
-            }
-            (&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
-                self.unify_integral_variable(v_id, IntType(v));
-                Ok(a)
-            }
-            (&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
-                self.unify_integral_variable(v_id, UintType(v));
-                Ok(b)
-            }
-            (&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
-                self.unify_integral_variable(v_id, UintType(v));
-                Ok(a)
-            }
-
-            // Relate floating-point variables to other types
-            (&ty::Infer(ty::FloatVar(a_id)), &ty::Infer(ty::FloatVar(b_id))) => {
-                self.inner.borrow_mut().float_unification_table().union(a_id, b_id);
-                Ok(a)
-            }
-            (&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
-                self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
-                Ok(b)
-            }
-            (&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
-                self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
-                Ok(a)
-            }
-
-            // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
-            (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..))
-                if self.next_trait_solver() =>
-            {
-                bug!(
-                    "We do not expect to encounter `TyVar` this late in combine \
-                    -- they should have been handled earlier"
-                )
-            }
-            (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
-            | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _)
-                if self.next_trait_solver() =>
-            {
-                bug!("We do not expect to encounter `Fresh` variables in the new solver")
-            }
-
-            (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
-                match relation.structurally_relate_aliases() {
-                    StructurallyRelateAliases::Yes => {
-                        relate::structurally_relate_tys(relation, a, b)
-                    }
-                    StructurallyRelateAliases::No => {
-                        relation.register_alias_relate_predicate(a, b);
-                        Ok(a)
-                    }
-                }
-            }
-
-            // All other cases of inference are errors
-            (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
-                Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
-            }
-
-            // During coherence, opaque types should be treated as *possibly*
-            // equal to any other type (except for possibly itself). This is an
-            // extremely heavy hammer, but can be relaxed in a forwards-compatible
-            // way later.
-            (&ty::Alias(ty::Opaque, _), _) | (_, &ty::Alias(ty::Opaque, _)) if self.intercrate => {
-                relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
-                Ok(a)
-            }
-
-            _ => relate::structurally_relate_tys(relation, a, b),
-        }
-    }
-
-    pub fn super_combine_consts<R>(
-        &self,
-        relation: &mut R,
-        a: ty::Const<'tcx>,
-        b: ty::Const<'tcx>,
-    ) -> RelateResult<'tcx, ty::Const<'tcx>>
-    where
-        R: PredicateEmittingRelation<InferCtxt<'tcx>>,
-    {
-        debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
-        debug_assert!(!a.has_escaping_bound_vars());
-        debug_assert!(!b.has_escaping_bound_vars());
-
-        if a == b {
-            return Ok(a);
-        }
-
-        let a = self.shallow_resolve_const(a);
-        let b = self.shallow_resolve_const(b);
-
-        match (a.kind(), b.kind()) {
-            (
-                ty::ConstKind::Infer(InferConst::Var(a_vid)),
-                ty::ConstKind::Infer(InferConst::Var(b_vid)),
-            ) => {
-                self.inner.borrow_mut().const_unification_table().union(a_vid, b_vid);
-                Ok(a)
-            }
-
-            (
-                ty::ConstKind::Infer(InferConst::EffectVar(a_vid)),
-                ty::ConstKind::Infer(InferConst::EffectVar(b_vid)),
-            ) => {
-                self.inner.borrow_mut().effect_unification_table().union(a_vid, b_vid);
-                Ok(a)
-            }
-
-            // All other cases of inference with other variables are errors.
-            (
-                ty::ConstKind::Infer(InferConst::Var(_) | InferConst::EffectVar(_)),
-                ty::ConstKind::Infer(_),
-            )
-            | (
-                ty::ConstKind::Infer(_),
-                ty::ConstKind::Infer(InferConst::Var(_) | InferConst::EffectVar(_)),
-            ) => {
-                bug!(
-                    "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}"
-                )
-            }
-
-            (ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
-                self.instantiate_const_var(relation, true, vid, b)?;
-                Ok(b)
-            }
-
-            (_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
-                self.instantiate_const_var(relation, false, vid, a)?;
-                Ok(a)
-            }
-
-            (ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
-                Ok(self.unify_effect_variable(vid, b))
-            }
-
-            (_, ty::ConstKind::Infer(InferConst::EffectVar(vid))) => {
-                Ok(self.unify_effect_variable(vid, a))
-            }
-
-            (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
-                if self.tcx.features().generic_const_exprs || self.next_trait_solver() =>
-            {
-                match relation.structurally_relate_aliases() {
-                    StructurallyRelateAliases::No => {
-                        relation.register_predicates([if self.next_trait_solver() {
-                            ty::PredicateKind::AliasRelate(
-                                a.into(),
-                                b.into(),
-                                ty::AliasRelationDirection::Equate,
-                            )
-                        } else {
-                            ty::PredicateKind::ConstEquate(a, b)
-                        }]);
-
-                        Ok(b)
-                    }
-                    StructurallyRelateAliases::Yes => {
-                        relate::structurally_relate_consts(relation, a, b)
-                    }
-                }
-            }
-            _ => relate::structurally_relate_consts(relation, a, b),
-        }
-    }
-
-    #[inline(always)]
-    fn unify_integral_variable(&self, vid: ty::IntVid, val: ty::IntVarValue) {
-        self.inner.borrow_mut().int_unification_table().union_value(vid, val);
-    }
-
-    #[inline(always)]
-    fn unify_float_variable(&self, vid: ty::FloatVid, val: ty::FloatVarValue) {
-        self.inner.borrow_mut().float_unification_table().union_value(vid, val);
-    }
-
-    fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        self.inner
-            .borrow_mut()
-            .effect_unification_table()
-            .union_value(vid, EffectVarValue::Known(val));
-        val
-    }
-}
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 726a2296d11..7049444db9b 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -183,7 +183,7 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
     #[instrument(level = "debug", skip(self, relation))]
-    pub(super) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
+    pub(crate) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
         &self,
         relation: &mut R,
         target_is_expected: bool,
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 8cec312abf7..fc208a08471 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -18,6 +18,7 @@
 //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
 
 use rustc_middle::traits::solve::Goal;
+use rustc_middle::ty::relate::combine::InferCtxtCombineExt;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt};
 use rustc_span::Span;
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index baab5bb274a..e156f72d78d 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -3,12 +3,10 @@
 //! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc).
 
 pub use rustc_middle::ty::relate::RelateResult;
-pub use rustc_next_trait_solver::relate::*;
-
-pub use self::combine::PredicateEmittingRelation;
+pub use rustc_type_ir::relate::combine::PredicateEmittingRelation;
+pub use rustc_type_ir::relate::*;
 
 #[allow(hidden_glob_reexports)]
-pub(super) mod combine;
 mod generalize;
 mod higher_ranked;
 pub(super) mod lattice;
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index d99acabb825..d2dc4589103 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -1,4 +1,5 @@
 use rustc_middle::traits::solve::Goal;
+use rustc_middle::ty::relate::combine::InferCtxtCombineExt;
 use rustc_middle::ty::relate::{
     Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
 };