1
Fork 0

Use SolverRelating in favor of TypeRelating in the old solver where possible

This commit is contained in:
Michael Goulet 2024-10-04 13:30:51 -04:00
parent 30a2ecddb4
commit a4cd2202ef
4 changed files with 92 additions and 39 deletions

View file

@ -27,11 +27,14 @@
use relate::lattice::{LatticeOp, LatticeOpKind}; use relate::lattice::{LatticeOp, LatticeOpKind};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate;
use rustc_middle::ty::{Const, ImplSubject}; use rustc_middle::ty::{Const, ImplSubject};
use super::*; use super::*;
use crate::infer::relate::type_relating::TypeRelating; use crate::infer::relate::type_relating::TypeRelating;
use crate::infer::relate::{Relate, TypeRelation}; 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. /// Whether we should define opaque types or just treat them opaquely.
/// ///
@ -109,15 +112,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where where
T: ToTrace<'tcx>, T: ToTrace<'tcx>,
{ {
let mut op = TypeRelating::new( if self.infcx.next_trait_solver {
self.infcx, NextSolverRelate::relate(
ToTrace::to_trace(self.cause, expected, actual), self.infcx,
self.param_env, self.param_env,
define_opaque_types, expected,
ty::Contravariant, ty::Contravariant,
); actual,
op.relate(expected, actual)?; )
Ok(InferOk { value: (), obligations: op.into_obligations() }) .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`. /// Makes `expected <: actual`.
@ -130,15 +144,20 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where where
T: ToTrace<'tcx>, T: ToTrace<'tcx>,
{ {
let mut op = TypeRelating::new( if self.infcx.next_trait_solver {
self.infcx, NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Covariant, actual)
ToTrace::to_trace(self.cause, expected, actual), .map(|goals| self.goals_to_obligations(goals))
self.param_env, } else {
define_opaque_types, let mut op = TypeRelating::new(
ty::Covariant, self.infcx,
); ToTrace::to_trace(self.cause, expected, actual),
op.relate(expected, actual)?; self.param_env,
Ok(InferOk { value: (), obligations: op.into_obligations() }) define_opaque_types,
ty::Covariant,
);
op.relate(expected, actual)?;
Ok(InferOk { value: (), obligations: op.into_obligations() })
}
} }
/// Makes `expected == actual`. /// Makes `expected == actual`.
@ -170,15 +189,20 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where where
T: Relate<TyCtxt<'tcx>>, T: Relate<TyCtxt<'tcx>>,
{ {
let mut op = TypeRelating::new( if self.infcx.next_trait_solver {
self.infcx, NextSolverRelate::relate(self.infcx, self.param_env, expected, ty::Invariant, actual)
trace, .map(|goals| self.goals_to_obligations(goals))
self.param_env, } else {
define_opaque_types, let mut op = TypeRelating::new(
ty::Invariant, self.infcx,
); trace,
op.relate(expected, actual)?; self.param_env,
Ok(InferOk { value: (), obligations: op.into_obligations() }) define_opaque_types,
ty::Invariant,
);
op.relate(expected, actual)?;
Ok(InferOk { value: (), obligations: op.into_obligations() })
}
} }
pub fn relate<T>( pub fn relate<T>(
@ -223,6 +247,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
let value = op.relate(expected, actual)?; let value = op.relate(expected, actual)?;
Ok(InferOk { value, obligations: op.into_obligations() }) Ok(InferOk { value, obligations: op.into_obligations() })
} }
fn goals_to_obligations(
&self,
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
) -> 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> { impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {

View file

@ -58,6 +58,7 @@ impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> {
define_opaque_types: DefineOpaqueTypes, define_opaque_types: DefineOpaqueTypes,
ambient_variance: ty::Variance, ambient_variance: ty::Variance,
) -> TypeRelating<'infcx, 'tcx> { ) -> TypeRelating<'infcx, 'tcx> {
assert!(!infcx.next_trait_solver);
TypeRelating { TypeRelating {
infcx, infcx,
trace, trace,
@ -190,9 +191,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
if self.define_opaque_types == DefineOpaqueTypes::Yes if self.define_opaque_types == DefineOpaqueTypes::Yes && def_id.is_local() =>
&& def_id.is_local()
&& !infcx.next_trait_solver() =>
{ {
self.register_goals(infcx.handle_opaque_type( self.register_goals(infcx.handle_opaque_type(
a, a,

View file

@ -836,7 +836,7 @@ where
lhs: T, lhs: T,
rhs: T, rhs: T,
) -> Result<Vec<Goal<I, I::Predicate>>, NoSolution> { ) -> Result<Vec<Goal<I, I::Predicate>>, 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<T: TypeFoldable<I> + Copy>( pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<I> + Copy>(

View file

@ -1,5 +1,5 @@
pub use rustc_type_ir::relate::*; 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 rustc_type_ir::{self as ty, InferCtxtLike, Interner};
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@ -13,14 +13,20 @@ pub trait RelateExt: InferCtxtLike {
lhs: T, lhs: T,
variance: ty::Variance, variance: ty::Variance,
rhs: T, rhs: T,
) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>; ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>,
>;
fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>( fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>(
&self, &self,
param_env: <Self::Interner as Interner>::ParamEnv, param_env: <Self::Interner as Interner>::ParamEnv,
lhs: T, lhs: T,
rhs: T, rhs: T,
) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>; ) -> Result<
Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>,
>;
} }
impl<Infcx: InferCtxtLike> RelateExt for Infcx { impl<Infcx: InferCtxtLike> RelateExt for Infcx {
@ -30,8 +36,10 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
lhs: T, lhs: T,
variance: ty::Variance, variance: ty::Variance,
rhs: T, rhs: T,
) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution> ) -> Result<
{ Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>,
> {
let mut relate = let mut relate =
SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env); SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env);
relate.relate(lhs, rhs)?; relate.relate(lhs, rhs)?;
@ -43,8 +51,10 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
param_env: <Self::Interner as Interner>::ParamEnv, param_env: <Self::Interner as Interner>::ParamEnv,
lhs: T, lhs: T,
rhs: T, rhs: T,
) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution> ) -> Result<
{ Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
TypeError<Self::Interner>,
> {
let mut relate = let mut relate =
SolverRelating::new(self, StructurallyRelateAliases::Yes, ty::Invariant, param_env); SolverRelating::new(self, StructurallyRelateAliases::Yes, ty::Invariant, param_env);
relate.relate(lhs, rhs)?; relate.relate(lhs, rhs)?;
@ -91,7 +101,7 @@ where
Infcx: InferCtxtLike<Interner = I>, Infcx: InferCtxtLike<Interner = I>,
I: Interner, I: Interner,
{ {
fn new( pub fn new(
infcx: &'infcx Infcx, infcx: &'infcx Infcx,
structurally_relate_aliases: StructurallyRelateAliases, structurally_relate_aliases: StructurallyRelateAliases,
ambient_variance: ty::Variance, ambient_variance: ty::Variance,