diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 1b99effabc0..8c943a961e7 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -27,11 +27,14 @@ use relate::lattice::{LatticeOp, LatticeOpKind}; use rustc_middle::bug; +use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate; use rustc_middle::ty::{Const, ImplSubject}; use super::*; use crate::infer::relate::type_relating::TypeRelating; use crate::infer::relate::{Relate, TypeRelation}; +use crate::traits::Obligation; +use crate::traits::solve::Goal; /// Whether we should define opaque types or just treat them opaquely. /// @@ -109,15 +112,26 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: ToTrace<'tcx>, { - let mut op = TypeRelating::new( - self.infcx, - ToTrace::to_trace(self.cause, expected, actual), - self.param_env, - define_opaque_types, - ty::Contravariant, - ); - op.relate(expected, actual)?; - Ok(InferOk { value: (), obligations: op.into_obligations() }) + if self.infcx.next_trait_solver { + NextSolverRelate::relate( + self.infcx, + self.param_env, + expected, + ty::Contravariant, + actual, + ) + .map(|goals| self.goals_to_obligations(goals)) + } else { + let mut op = TypeRelating::new( + self.infcx, + ToTrace::to_trace(self.cause, expected, actual), + self.param_env, + define_opaque_types, + ty::Contravariant, + ); + op.relate(expected, actual)?; + Ok(InferOk { value: (), obligations: op.into_obligations() }) + } } /// Makes `expected <: actual`. @@ -130,15 +144,20 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: ToTrace<'tcx>, { - let mut op = TypeRelating::new( - self.infcx, - ToTrace::to_trace(self.cause, expected, actual), - self.param_env, - define_opaque_types, - ty::Covariant, - ); - op.relate(expected, actual)?; - Ok(InferOk { value: (), obligations: op.into_obligations() }) + if self.infcx.next_trait_solver { + NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Covariant, actual) + .map(|goals| self.goals_to_obligations(goals)) + } else { + let mut op = TypeRelating::new( + self.infcx, + ToTrace::to_trace(self.cause, expected, actual), + self.param_env, + define_opaque_types, + ty::Covariant, + ); + op.relate(expected, actual)?; + Ok(InferOk { value: (), obligations: op.into_obligations() }) + } } /// Makes `expected == actual`. @@ -170,15 +189,20 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: Relate>, { - let mut op = TypeRelating::new( - self.infcx, - trace, - self.param_env, - define_opaque_types, - ty::Invariant, - ); - op.relate(expected, actual)?; - Ok(InferOk { value: (), obligations: op.into_obligations() }) + if self.infcx.next_trait_solver { + NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Invariant, actual) + .map(|goals| self.goals_to_obligations(goals)) + } else { + let mut op = TypeRelating::new( + self.infcx, + trace, + self.param_env, + define_opaque_types, + ty::Invariant, + ); + op.relate(expected, actual)?; + Ok(InferOk { value: (), obligations: op.into_obligations() }) + } } pub fn relate( @@ -223,6 +247,26 @@ impl<'a, 'tcx> At<'a, 'tcx> { let value = op.relate(expected, actual)?; Ok(InferOk { value, obligations: op.into_obligations() }) } + + fn goals_to_obligations( + &self, + goals: Vec>>, + ) -> InferOk<'tcx, ()> { + InferOk { + value: (), + obligations: goals + .into_iter() + .map(|goal| { + Obligation::new( + self.infcx.tcx, + self.cause.clone(), + goal.param_env, + goal.predicate, + ) + }) + .collect(), + } + } } impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 6129faf3d50..1cc968ca275 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -58,6 +58,7 @@ impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> { define_opaque_types: DefineOpaqueTypes, ambient_variance: ty::Variance, ) -> TypeRelating<'infcx, 'tcx> { + assert!(!infcx.next_trait_solver); TypeRelating { infcx, trace, @@ -190,9 +191,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, 'tcx> { (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) - if self.define_opaque_types == DefineOpaqueTypes::Yes - && def_id.is_local() - && !infcx.next_trait_solver() => + if self.define_opaque_types == DefineOpaqueTypes::Yes && def_id.is_local() => { self.register_goals(infcx.handle_opaque_type( a, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 970ef905dfd..785bed4ec69 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -836,7 +836,7 @@ where lhs: T, rhs: T, ) -> Result>, NoSolution> { - self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs) + Ok(self.delegate.relate(param_env, lhs, ty::Variance::Invariant, rhs)?) } pub(super) fn instantiate_binder_with_infer + Copy>( diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index a2521eda6dd..edbfaed9709 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -1,5 +1,5 @@ pub use rustc_type_ir::relate::*; -use rustc_type_ir::solve::{Goal, NoSolution}; +use rustc_type_ir::solve::Goal; use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; use tracing::{debug, instrument}; @@ -13,14 +13,20 @@ pub trait RelateExt: InferCtxtLike { lhs: T, variance: ty::Variance, rhs: T, - ) -> Result::Predicate>>, NoSolution>; + ) -> Result< + Vec::Predicate>>, + TypeError, + >; fn eq_structurally_relating_aliases>( &self, param_env: ::ParamEnv, lhs: T, rhs: T, - ) -> Result::Predicate>>, NoSolution>; + ) -> Result< + Vec::Predicate>>, + TypeError, + >; } impl RelateExt for Infcx { @@ -30,8 +36,10 @@ impl RelateExt for Infcx { lhs: T, variance: ty::Variance, rhs: T, - ) -> Result::Predicate>>, NoSolution> - { + ) -> Result< + Vec::Predicate>>, + TypeError, + > { let mut relate = SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env); relate.relate(lhs, rhs)?; @@ -43,8 +51,10 @@ impl RelateExt for Infcx { param_env: ::ParamEnv, lhs: T, rhs: T, - ) -> Result::Predicate>>, NoSolution> - { + ) -> Result< + Vec::Predicate>>, + TypeError, + > { let mut relate = SolverRelating::new(self, StructurallyRelateAliases::Yes, ty::Invariant, param_env); relate.relate(lhs, rhs)?; @@ -91,7 +101,7 @@ where Infcx: InferCtxtLike, I: Interner, { - fn new( + pub fn new( infcx: &'infcx Infcx, structurally_relate_aliases: StructurallyRelateAliases, ambient_variance: ty::Variance,