diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index e72c21e8fadf4..cfc14d146bd2c 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -11,7 +11,7 @@ use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::FnMutDelegate; -use rustc_middle::ty::relate::combine::InferCtxtCombineExt; +use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; @@ -363,7 +363,7 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), ) if a_def_id == b_def_id || infcx.next_trait_solver() => { - infcx.super_combine_tys(self, a, b).map(|_| ()).or_else(|err| { + super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| { // This behavior is only there for the old solver, the new solver // shouldn't ever fail. Instead, it unconditionally emits an // alias-relate goal. @@ -386,7 +386,7 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { debug!(?a, ?b, ?self.ambient_variance); // Will also handle unification of `IntVar` and `FloatVar`. - self.type_checker.infcx.super_combine_tys(self, a, b)?; + super_combine_tys(&self.type_checker.infcx.infcx, self, a, b)?; } } @@ -423,7 +423,7 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); - self.type_checker.infcx.super_combine_consts(self, a, b) + super_combine_consts(&self.type_checker.infcx.infcx, self, a, b) } #[instrument(skip(self), level = "trace")] diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index fc208a084718e..7eb61abfbc124 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -18,7 +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::combine::{super_combine_consts, super_combine_tys}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt}; use rustc_span::Span; @@ -149,7 +149,7 @@ impl<'tcx> TypeRelation> for LatticeOp<'_, 'tcx> { ( &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), - ) if a_def_id == b_def_id => infcx.super_combine_tys(self, a, b), + ) if a_def_id == b_def_id => super_combine_tys(infcx, self, a, b), (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) @@ -164,7 +164,7 @@ impl<'tcx> TypeRelation> for LatticeOp<'_, 'tcx> { Ok(a) } - _ => infcx.super_combine_tys(self, a, b), + _ => super_combine_tys(infcx, self, a, b), } } @@ -192,7 +192,7 @@ impl<'tcx> TypeRelation> for LatticeOp<'_, 'tcx> { a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - self.infcx.super_combine_consts(self, a, b) + super_combine_consts(self.infcx, self, a, b) } fn binders( diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 1cc968ca27550..35103c070c27d 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,5 +1,5 @@ use rustc_middle::traits::solve::Goal; -use rustc_middle::ty::relate::combine::InferCtxtCombineExt; +use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; use rustc_middle::ty::relate::{ Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances, }; @@ -186,7 +186,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, 'tcx> { &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }), ) if a_def_id == b_def_id => { - infcx.super_combine_tys(self, a, b)?; + super_combine_tys(infcx, self, a, b)?; } (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) @@ -202,7 +202,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, 'tcx> { } _ => { - infcx.super_combine_tys(self, a, b)?; + super_combine_tys(infcx, self, a, b)?; } } @@ -257,7 +257,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, 'tcx> { a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - self.infcx.super_combine_consts(self, a, b) + super_combine_consts(self.infcx, self, a, b) } fn binders( diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 9dfcde609c71e..60a953801a479 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -39,217 +39,208 @@ where fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); } -pub trait InferCtxtCombineExt: InferCtxtLike { - fn super_combine_tys(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult - where - R: PredicateEmittingRelation; - - fn super_combine_consts( - &self, - relation: &mut R, - a: I::Const, - b: I::Const, - ) -> RelateResult - where - R: PredicateEmittingRelation; -} - -impl> InferCtxtCombineExt for Infcx { - fn super_combine_tys(&self, relation: &mut R, a: I::Ty, b: I::Ty) -> RelateResult - where - R: PredicateEmittingRelation, - { - debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::(), 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.cx(), e)); - } +pub fn super_combine_tys( + infcx: &Infcx, + relation: &mut R, + a: I::Ty, + b: I::Ty, +) -> RelateResult +where + Infcx: InferCtxtLike, + I: Interner, + R: PredicateEmittingRelation, +{ + debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::(), 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)) => { + infcx.set_tainted_by_errors(e); + return Ok(Ty::new_error(infcx.cx(), e)); + } - // Relate integral variables to other types - (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => { - self.equate_int_vids_raw(a_id, b_id); - Ok(a) - } - (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => { - self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); - Ok(b) - } - (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => { - self.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); - Ok(a) - } - (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => { - self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); - Ok(b) - } - (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => { - self.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); - Ok(a) - } + // Relate integral variables to other types + (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => { + infcx.equate_int_vids_raw(a_id, b_id); + Ok(a) + } + (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => { + infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); + Ok(b) + } + (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => { + infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v)); + Ok(a) + } + (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => { + infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); + Ok(b) + } + (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => { + infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v)); + Ok(a) + } - // Relate floating-point variables to other types - (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => { - self.equate_float_vids_raw(a_id, b_id); - Ok(a) - } - (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => { - self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v)); - Ok(b) - } - (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => { - self.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v)); - Ok(a) - } + // Relate floating-point variables to other types + (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => { + infcx.equate_float_vids_raw(a_id, b_id); + Ok(a) + } + (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => { + infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v)); + Ok(b) + } + (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => { + infcx.instantiate_float_var_raw(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() => - { - panic!( - "We do not expect to encounter `TyVar` this late in combine \ + // 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 infcx.next_trait_solver() => + { + panic!( + "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() => - { - panic!("We do not expect to encounter `Fresh` variables in the new solver") - } + ) + } + (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))) + | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) + if infcx.next_trait_solver() => + { + panic!("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 => structurally_relate_tys(relation, a, b), - StructurallyRelateAliases::No => { - relation.register_alias_relate_predicate(a, b); - Ok(a) - } + (_, ty::Alias(..)) | (ty::Alias(..), _) if infcx.next_trait_solver() => { + match relation.structurally_relate_aliases() { + StructurallyRelateAliases::Yes => 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))) - } + // All other cases of inference are errors + (ty::Infer(_), _) | (_, ty::Infer(_)) => { + Err(TypeError::Sorts(ExpectedFound::new(true, a, b))) + } - (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => { - match self.solver_mode() { - SolverMode::Normal => { - assert!(!self.next_trait_solver()); - structurally_relate_tys(relation, 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. - SolverMode::Coherence => { - relation - .register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]); - Ok(a) - } + (ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => { + match infcx.solver_mode() { + SolverMode::Normal => { + assert!(!infcx.next_trait_solver()); + structurally_relate_tys(relation, a, b) + } + // During coherence, opaque types should be treated as *possibly* + // equal to any other type (except for possibly itinfcx). This is an + // extremely heavy hammer, but can be relaxed in a forwards-compatible + // way later. + SolverMode::Coherence => { + relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]); + Ok(a) } } - - _ => structurally_relate_tys(relation, a, b), } + + _ => structurally_relate_tys(relation, a, b), } +} - fn super_combine_consts( - &self, - relation: &mut R, - a: I::Const, - b: I::Const, - ) -> RelateResult - where - R: PredicateEmittingRelation, - { - debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::(), 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(ty::InferConst::Var(a_vid)), - ty::ConstKind::Infer(ty::InferConst::Var(b_vid)), - ) => { - self.equate_const_vids_raw(a_vid, b_vid); - Ok(a) - } +pub fn super_combine_consts( + infcx: &Infcx, + relation: &mut R, + a: I::Const, + b: I::Const, +) -> RelateResult +where + Infcx: InferCtxtLike, + I: Interner, + R: PredicateEmittingRelation, +{ + debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::(), a, b); + debug_assert!(!a.has_escaping_bound_vars()); + debug_assert!(!b.has_escaping_bound_vars()); - ( - ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)), - ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)), - ) => { - self.equate_effect_vids_raw(a_vid, b_vid); - Ok(a) - } + if a == b { + return Ok(a); + } + + let a = infcx.shallow_resolve_const(a); + let b = infcx.shallow_resolve_const(b); - // All other cases of inference with other variables are errors. - ( - ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), - ty::ConstKind::Infer(_), + match (a.kind(), b.kind()) { + ( + ty::ConstKind::Infer(ty::InferConst::Var(a_vid)), + ty::ConstKind::Infer(ty::InferConst::Var(b_vid)), + ) => { + infcx.equate_const_vids_raw(a_vid, b_vid); + Ok(a) + } + + ( + ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)), + ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)), + ) => { + infcx.equate_effect_vids_raw(a_vid, b_vid); + Ok(a) + } + + // All other cases of inference with other variables are errors. + ( + ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), + ty::ConstKind::Infer(_), + ) + | ( + ty::ConstKind::Infer(_), + ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), + ) => { + panic!( + "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}" ) - | ( - ty::ConstKind::Infer(_), - ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), - ) => { - panic!( - "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}" - ) - } + } - (ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => { - self.instantiate_const_var_raw(relation, true, vid, b)?; - Ok(b) - } + (ty::ConstKind::Infer(ty::InferConst::Var(vid)), _) => { + infcx.instantiate_const_var_raw(relation, true, vid, b)?; + Ok(b) + } - (_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => { - self.instantiate_const_var_raw(relation, false, vid, a)?; - Ok(a) - } + (_, ty::ConstKind::Infer(ty::InferConst::Var(vid))) => { + infcx.instantiate_const_var_raw(relation, false, vid, a)?; + Ok(a) + } - (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => { - self.instantiate_effect_var_raw(vid, b); - Ok(b) - } + (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => { + infcx.instantiate_effect_var_raw(vid, b); + Ok(b) + } - (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => { - self.instantiate_effect_var_raw(vid, a); - Ok(a) - } + (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => { + infcx.instantiate_effect_var_raw(vid, a); + Ok(a) + } - (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) - if self.cx().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 => structurally_relate_consts(relation, a, b), + (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) + if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() => + { + match relation.structurally_relate_aliases() { + StructurallyRelateAliases::No => { + relation.register_predicates([if infcx.next_trait_solver() { + ty::PredicateKind::AliasRelate( + a.into(), + b.into(), + ty::AliasRelationDirection::Equate, + ) + } else { + ty::PredicateKind::ConstEquate(a, b) + }]); + + Ok(b) } + StructurallyRelateAliases::Yes => structurally_relate_consts(relation, a, b), } - _ => structurally_relate_consts(relation, a, b), } + _ => structurally_relate_consts(relation, a, b), } } diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index edbfaed97095b..ad10ad5af9caf 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -3,7 +3,7 @@ use rustc_type_ir::solve::Goal; use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; use tracing::{debug, instrument}; -use self::combine::{InferCtxtCombineExt, PredicateEmittingRelation}; +use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys}; use crate::data_structures::DelayedSet; pub trait RelateExt: InferCtxtLike { @@ -228,7 +228,7 @@ where } _ => { - self.infcx.super_combine_tys(self, a, b)?; + super_combine_tys(self.infcx, self, a, b)?; } } @@ -255,7 +255,7 @@ where #[instrument(skip(self), level = "trace")] fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult { - self.infcx.super_combine_consts(self, a, b) + super_combine_consts(self.infcx, self, a, b) } fn binders(