Skip to content

Commit

Permalink
Use SolverRelating in favor of TypeRelating in the old solver where p…
Browse files Browse the repository at this point in the history
…ossible
  • Loading branch information
compiler-errors committed Oct 7, 2024
1 parent e43376a commit 5fa0570
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 42 deletions.
110 changes: 77 additions & 33 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
//! things. (That system should probably be refactored.)

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::{Relate, TypeRelation};
use crate::traits::Obligation;
use crate::traits::solve::Goal;

/// Whether we should define opaque types or just treat them opaquely.
///
Expand Down Expand Up @@ -108,14 +110,25 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
let mut fields = CombineFields::new(
self.infcx,
ToTrace::to_trace(self.cause, expected, actual),
self.param_env,
define_opaque_types,
);
fields.sup().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.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 fields = CombineFields::new(
self.infcx,
ToTrace::to_trace(self.cause, expected, actual),
self.param_env,
define_opaque_types,
);
fields.sup().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}
}

/// Makes `expected <: actual`.
Expand All @@ -128,14 +141,19 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
let mut fields = CombineFields::new(
self.infcx,
ToTrace::to_trace(self.cause, expected, actual),
self.param_env,
define_opaque_types,
);
fields.sub().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.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 fields = CombineFields::new(
self.infcx,
ToTrace::to_trace(self.cause, expected, actual),
self.param_env,
define_opaque_types,
);
fields.sub().relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}
}

/// Makes `expected == actual`.
Expand Down Expand Up @@ -167,23 +185,29 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: Relate<TyCtxt<'tcx>>,
{
let mut fields = CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types);
fields.equate().relate(expected, actual)?;
Ok(InferOk {
value: (),
obligations: fields
.goals
.into_iter()
.map(|goal| {
Obligation::new(
self.infcx.tcx,
fields.trace.cause.clone(),
goal.param_env,
goal.predicate,
)
})
.collect(),
})
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 fields =
CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types);
fields.equate().relate(expected, actual)?;
Ok(InferOk {
value: (),
obligations: fields
.goals
.into_iter()
.map(|goal| {
Obligation::new(
self.infcx.tcx,
fields.trace.cause.clone(),
goal.param_env,
goal.predicate,
)
})
.collect(),
})
}
}

pub fn relate<T>(
Expand Down Expand Up @@ -255,6 +279,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
let value = fields.glb().relate(expected, actual)?;
Ok(InferOk { value, obligations: fields.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> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ where
lhs: T,
rhs: T,
) -> 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>(
Expand Down
26 changes: 18 additions & 8 deletions compiler/rustc_type_ir/src/relate/solver_relating.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -12,14 +12,20 @@ pub trait RelateExt: InferCtxtLike {
lhs: T,
variance: ty::Variance,
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>>(
&self,
param_env: <Self::Interner as Interner>::ParamEnv,
lhs: 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 {
Expand All @@ -29,8 +35,10 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
lhs: T,
variance: ty::Variance,
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 =
SolverRelating::new(self, StructurallyRelateAliases::No, variance, param_env);
relate.relate(lhs, rhs)?;
Expand All @@ -42,8 +50,10 @@ impl<Infcx: InferCtxtLike> RelateExt for Infcx {
param_env: <Self::Interner as Interner>::ParamEnv,
lhs: 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 =
SolverRelating::new(self, StructurallyRelateAliases::Yes, ty::Invariant, param_env);
relate.relate(lhs, rhs)?;
Expand All @@ -66,7 +76,7 @@ where
Infcx: InferCtxtLike<Interner = I>,
I: Interner,
{
fn new(
pub fn new(
infcx: &'infcx Infcx,
structurally_relate_aliases: StructurallyRelateAliases,
ambient_variance: ty::Variance,
Expand Down

0 comments on commit 5fa0570

Please sign in to comment.