diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index b2702eafd33b..8dd06187877c 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; +use rustc_infer::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; @@ -140,10 +140,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> ); } - fn normalization() -> NormalizationStrategy { - NormalizationStrategy::Eager - } - fn forbid_inference_vars() -> bool { true } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 7cc9e49b1b62..0c97217bd6a5 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -12,7 +12,7 @@ use crate::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues, QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse, }; -use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; +use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin}; use crate::traits::query::{Fallible, NoSolution}; @@ -717,10 +717,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { }); } - fn normalization() -> NormalizationStrategy { - NormalizationStrategy::Eager - } - fn forbid_inference_vars() -> bool { true } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a567b6acdbee..cb1e14aaeaf9 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -38,8 +38,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{ - self, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, - TypeVisitable, + self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, + TypeSuperFoldable, TypeVisitable, }; use rustc_middle::ty::{IntType, UintType}; use rustc_span::{Span, DUMMY_SP}; @@ -74,7 +74,7 @@ impl<'tcx> InferCtxt<'tcx> { b: Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> where - R: TypeRelation<'tcx>, + R: ObligationEmittingRelation<'tcx>, { let a_is_expected = relation.a_is_expected(); @@ -122,6 +122,15 @@ impl<'tcx> InferCtxt<'tcx> { Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b))) } + (ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => { + relation.register_type_equate_obligation(a.into(), b.into()); + Ok(b) + } + (_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => { + relation.register_type_equate_obligation(b.into(), a.into()); + Ok(a) + } + _ => ty::relate::super_relate_tys(relation, a, b), } } @@ -133,7 +142,7 @@ impl<'tcx> InferCtxt<'tcx> { b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> where - R: ConstEquateRelation<'tcx>, + R: ObligationEmittingRelation<'tcx>, { debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); if a == b { @@ -169,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> { // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { - relation.const_equate_obligation(a, b); + relation.register_const_equate_obligation(a, b); } return Ok(b); } @@ -177,7 +186,7 @@ impl<'tcx> InferCtxt<'tcx> { // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { - relation.const_equate_obligation(a, b); + relation.register_const_equate_obligation(a, b); } return Ok(a); } @@ -435,32 +444,21 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { Ok(Generalization { ty, needs_wf }) } - pub fn add_const_equate_obligation( + pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.obligations.extend(obligations.into_iter()); + } + + pub fn register_predicates( &mut self, - a_is_expected: bool, - a: ty::Const<'tcx>, - b: ty::Const<'tcx>, + obligations: impl IntoIterator>, ) { - let predicate = if a_is_expected { - ty::PredicateKind::ConstEquate(a, b) - } else { - ty::PredicateKind::ConstEquate(b, a) - }; - self.obligations.push(Obligation::new( - self.tcx(), - self.trace.cause.clone(), - self.param_env, - ty::Binder::dummy(predicate), - )); + self.obligations.extend(obligations.into_iter().map(|to_pred| { + Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred) + })) } pub fn mark_ambiguous(&mut self) { - self.obligations.push(Obligation::new( - self.tcx(), - self.trace.cause.clone(), - self.param_env, - ty::Binder::dummy(ty::PredicateKind::Ambiguous), - )); + self.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]); } } @@ -775,11 +773,42 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } -pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> { +pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { + /// Register obligations that must hold in order for this relation to hold + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>); + + /// Register predicates that must hold in order for this relation to hold. Uses + /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should + /// be used if control over the obligaton causes is required. + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ); + /// Register an obligation that both constants must be equal to each other. /// /// If they aren't equal then the relation doesn't hold. - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>); + fn register_const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { + let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; + + self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() { + ty::PredicateKind::AliasEq(a.into(), b.into()) + } else { + ty::PredicateKind::ConstEquate(a, b) + })]); + } + + /// Register an obligation that both types must be equal to each other. + /// + /// If they aren't equal then the relation doesn't hold. + fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; + + self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasEq( + a.into(), + b.into(), + ))]); + } } fn int_unification_error<'tcx>( diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 7db4d92a177a..742c01efff60 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -1,4 +1,6 @@ -use super::combine::{CombineFields, ConstEquateRelation, RelationDir}; +use crate::traits::PredicateObligations; + +use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir}; use super::Subtype; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; @@ -198,8 +200,15 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { } } -impl<'tcx> ConstEquateRelation<'tcx> for Equate<'_, '_, 'tcx> { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.fields.add_const_equate_obligation(self.a_is_expected, a, b); +impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> { + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ) { + self.fields.register_predicates(obligations); + } + + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.fields.register_obligations(obligations); } } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index b92b162a9786..74abca7bbea3 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -1,12 +1,11 @@ //! Greatest lower bound. See [`lattice`]. -use super::combine::CombineFields; +use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::InferCtxt; use super::Subtype; -use crate::infer::combine::ConstEquateRelation; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::{ObligationCause, PredicateObligations}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -136,10 +135,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, &self.fields.trace.cause } - fn add_obligations(&mut self, obligations: Vec>) { - self.fields.obligations.extend(obligations) - } - fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { let mut sub = self.fields.sub(self.a_is_expected); sub.relate(v, a)?; @@ -152,8 +147,15 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, } } -impl<'tcx> ConstEquateRelation<'tcx> for Glb<'_, '_, 'tcx> { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.fields.add_const_equate_obligation(self.a_is_expected, a, b); +impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ) { + self.fields.register_predicates(obligations); + } + + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.fields.register_obligations(obligations); } } diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs index 4dbb4b4d7b4d..f377ac1d19e9 100644 --- a/compiler/rustc_infer/src/infer/lattice.rs +++ b/compiler/rustc_infer/src/infer/lattice.rs @@ -17,11 +17,12 @@ //! //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) +use super::combine::ObligationEmittingRelation; use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::InferCtxt; -use crate::traits::{ObligationCause, PredicateObligation}; -use rustc_middle::ty::relate::{RelateResult, TypeRelation}; +use crate::traits::ObligationCause; +use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -30,13 +31,11 @@ use rustc_middle::ty::{self, Ty}; /// /// GLB moves "down" the lattice (to smaller values); LUB moves /// "up" the lattice (to bigger values). -pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> { +pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> { fn infcx(&self) -> &'f InferCtxt<'tcx>; fn cause(&self) -> &ObligationCause<'tcx>; - fn add_obligations(&mut self, obligations: Vec>); - fn define_opaque_types(&self) -> bool; // Relates the type `v` to `a` and `b` such that `v` represents @@ -113,7 +112,7 @@ where | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) if this.define_opaque_types() && def_id.is_local() => { - this.add_obligations( + this.register_obligations( infcx .handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())? .obligations, diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index f6e0554fd1f9..f997171b97f2 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -1,12 +1,11 @@ //! Least upper bound. See [`lattice`]. -use super::combine::CombineFields; +use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::InferCtxt; use super::Subtype; -use crate::infer::combine::ConstEquateRelation; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::{ObligationCause, PredicateObligations}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -127,12 +126,6 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { } } -impl<'tcx> ConstEquateRelation<'tcx> for Lub<'_, '_, 'tcx> { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.fields.add_const_equate_obligation(self.a_is_expected, a, b); - } -} - impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, 'tcx> { fn infcx(&self) -> &'infcx InferCtxt<'tcx> { self.fields.infcx @@ -142,10 +135,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, &self.fields.trace.cause } - fn add_obligations(&mut self, obligations: Vec>) { - self.fields.obligations.extend(obligations) - } - fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { let mut sub = self.fields.sub(self.a_is_expected); sub.relate(a, v)?; @@ -157,3 +146,16 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, self.fields.define_opaque_types } } + +impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ) { + self.fields.register_predicates(obligations); + } + + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.fields.register_obligations(obligations) + } +} diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 35918b8bae1c..e77924900a07 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -4,6 +4,7 @@ pub use self::LateBoundRegionConversionTime::*; pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; +pub use combine::ObligationEmittingRelation; use self::opaque_types::OpaqueTypeStorage; pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index a2cfe8d88816..1dd5062acaf0 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -21,11 +21,10 @@ //! thing we relate in chalk are basically domain goals and their //! constituents) -use crate::infer::combine::ConstEquateRelation; use crate::infer::InferCtxt; use crate::infer::{ConstVarValue, ConstVariableValue}; use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; @@ -36,11 +35,7 @@ use rustc_span::Span; use std::fmt::Debug; use std::ops::ControlFlow; -#[derive(PartialEq)] -pub enum NormalizationStrategy { - Lazy, - Eager, -} +use super::combine::ObligationEmittingRelation; pub struct TypeRelating<'me, 'tcx, D> where @@ -92,7 +87,7 @@ pub trait TypeRelatingDelegate<'tcx> { info: ty::VarianceDiagInfo<'tcx>, ); - fn register_obligations(&mut self, obligations: Vec>); + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>); /// Creates a new universe index. Used when instantiating placeholders. fn create_next_universe(&mut self) -> ty::UniverseIndex; @@ -125,9 +120,6 @@ pub trait TypeRelatingDelegate<'tcx> { /// relation stating that `'?0: 'a`). fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>; - /// Define the normalization strategy to use, eager or lazy. - fn normalization() -> NormalizationStrategy; - /// Enables some optimizations if we do not expect inference variables /// in the RHS of the relation. fn forbid_inference_vars() -> bool; @@ -265,38 +257,6 @@ where self.delegate.push_outlives(sup, sub, info); } - /// Relate a projection type and some value type lazily. This will always - /// succeed, but we push an additional `ProjectionEq` goal depending - /// on the value type: - /// - if the value type is any type `T` which is not a projection, we push - /// `ProjectionEq(projection = T)`. - /// - if the value type is another projection `other_projection`, we create - /// a new inference variable `?U` and push the two goals - /// `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`. - fn relate_projection_ty( - &mut self, - projection_ty: ty::AliasTy<'tcx>, - value_ty: Ty<'tcx>, - ) -> Ty<'tcx> { - use rustc_span::DUMMY_SP; - - match *value_ty.kind() { - ty::Alias(ty::Projection, other_projection_ty) => { - let var = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }); - // FIXME(lazy-normalization): This will always ICE, because the recursive - // call will end up in the _ arm below. - self.relate_projection_ty(projection_ty, var); - self.relate_projection_ty(other_projection_ty, var); - var - } - - _ => bug!("should never be invoked with eager normalization"), - } - } - /// Relate a type inference variable with a value type. This works /// by creating a "generalization" G of the value where all the /// lifetimes are replaced with fresh inference values. This @@ -335,12 +295,6 @@ where return Ok(value_ty); } - ty::Alias(ty::Projection, projection_ty) - if D::normalization() == NormalizationStrategy::Lazy => - { - return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid))); - } - _ => (), } @@ -627,18 +581,6 @@ where self.relate_opaques(a, b) } - (&ty::Alias(ty::Projection, projection_ty), _) - if D::normalization() == NormalizationStrategy::Lazy => - { - Ok(self.relate_projection_ty(projection_ty, b)) - } - - (_, &ty::Alias(ty::Projection, projection_ty)) - if D::normalization() == NormalizationStrategy::Lazy => - { - Ok(self.relate_projection_ty(projection_ty, a)) - } - _ => { debug!(?a, ?b, ?self.ambient_variance); @@ -813,17 +755,26 @@ where } } -impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D> +impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D> where D: TypeRelatingDelegate<'tcx>, { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.delegate.register_obligations(vec![Obligation::new( - self.tcx(), - ObligationCause::dummy(), - self.param_env(), - ty::Binder::dummy(ty::PredicateKind::ConstEquate(a, b)), - )]); + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ) { + self.delegate.register_obligations( + obligations + .into_iter() + .map(|to_pred| { + Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred) + }) + .collect(), + ); + } + + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.delegate.register_obligations(obligations); } } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 532fbd0ffe4c..bf1b34415470 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -1,8 +1,7 @@ use super::combine::{CombineFields, RelationDir}; -use super::SubregionOrigin; +use super::{ObligationEmittingRelation, SubregionOrigin}; -use crate::infer::combine::ConstEquateRelation; -use crate::traits::Obligation; +use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::TyVar; @@ -228,8 +227,15 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { } } -impl<'tcx> ConstEquateRelation<'tcx> for Sub<'_, '_, 'tcx> { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.fields.add_const_equate_obligation(self.a_is_expected, a, b); +impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> { + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ) { + self.fields.register_predicates(obligations); + } + + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + self.fields.register_obligations(obligations); } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d07d9190e011..bf36b3e5ada2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2230,6 +2230,10 @@ impl<'tcx> TyCtxt<'tcx> { }) ) } + + pub fn trait_solver_next(self) -> bool { + self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next + } } impl<'tcx> TyCtxtAt<'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs index ba9ee57d4099..9474c70cb535 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs @@ -1,5 +1,7 @@ use crate::infer::InferCtxt; +use rustc_infer::infer::ObligationEmittingRelation; +use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -88,3 +90,16 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } } + +impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { + fn register_obligations(&mut self, _obligations: PredicateObligations<'tcx>) { + // FIXME(deferred_projection_equality) + } + + fn register_predicates( + &mut self, + _obligations: impl IntoIterator>, + ) { + // FIXME(deferred_projection_equality) + } +}