Skip to content

Introduce SolverRelating type relation to the new solver code #128744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {

self.type_checker.infcx.instantiate_ty_var(
self,
StructurallyRelateAliases::No,
opaque_is_expected,
ty_vid,
variance,
Expand Down Expand Up @@ -353,9 +354,14 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
);
}

(&ty::Infer(ty::TyVar(a_vid)), _) => {
infcx.instantiate_ty_var(self, true, a_vid, self.ambient_variance, b)?
}
(&ty::Infer(ty::TyVar(a_vid)), _) => infcx.instantiate_ty_var(
self,
StructurallyRelateAliases::No,
true,
a_vid,
self.ambient_variance,
b,
)?,

(
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
Expand Down Expand Up @@ -524,10 +530,6 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating
self.locations.span(self.type_checker.body)
}

fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
StructurallyRelateAliases::No
}

fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.type_checker.param_env
}
Expand Down
45 changes: 2 additions & 43 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rustc_middle::bug;
use rustc_middle::ty::{Const, ImplSubject};

use super::*;
use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
use crate::infer::relate::{Relate, TypeRelation};
use crate::traits::Obligation;

/// Whether we should define opaque types or just treat them opaquely.
Expand Down Expand Up @@ -160,7 +160,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
self.param_env,
define_opaque_types,
);
fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
fields.equate().relate(expected, actual)?;
Ok(InferOk {
value: (),
obligations: fields
Expand All @@ -178,28 +178,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
})
}

/// Equates `expected` and `found` while structurally relating aliases.
/// This should only be used inside of the next generation trait solver
/// when relating rigid aliases.
pub fn eq_structurally_relating_aliases<T>(
self,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
assert!(self.infcx.next_trait_solver());
let mut fields = CombineFields::new(
self.infcx,
ToTrace::to_trace(self.cause, true, expected, actual),
self.param_env,
DefineOpaqueTypes::Yes,
);
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
Ok(InferOk { value: (), obligations: fields.into_obligations() })
}

pub fn relate<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand Down Expand Up @@ -249,25 +227,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
Ok(fields.goals)
}

/// Used in the new solver since we don't care about tracking an `ObligationCause`.
pub fn eq_structurally_relating_aliases_no_trace<T>(
self,
expected: T,
actual: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
where
T: Relate<TyCtxt<'tcx>>,
{
let mut fields = CombineFields::new(
self.infcx,
TypeTrace::dummy(self.cause),
self.param_env,
DefineOpaqueTypes::Yes,
);
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
Ok(fields.goals)
}

/// Computes the least-upper-bound, or mutual supertype, of two
/// values. The order of the arguments doesn't matter, but since
/// this can result in an error (e.g., if asked to compute LUB of
Expand Down
130 changes: 106 additions & 24 deletions compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
///! Definition of `InferCtxtLike` from the librarified type layer.
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::solve::{Goal, NoSolution, SolverMode};
use rustc_middle::infer::unify_key::EffectVarValue;
use rustc_middle::traits::solve::SolverMode;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::DUMMY_SP;
use rustc_type_ir::relate::Relate;
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
use rustc_type_ir::relate::combine::PredicateEmittingRelation;
use rustc_type_ir::relate::StructurallyRelateAliases;
use rustc_type_ir::InferCtxtLike;

use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
use crate::infer::RelateResult;

impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
type Interner = TyCtxt<'tcx>;
Expand Down Expand Up @@ -131,30 +134,14 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
self.enter_forall(value, f)
}

fn relate<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
variance: ty::Variance,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
}

fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env)
.eq_structurally_relating_aliases_no_trace(lhs, rhs)
}

fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.shallow_resolve(ty)
}

fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
self.shallow_resolve_const(ct)
}

fn resolve_vars_if_possible<T>(&self, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
Expand All @@ -167,10 +154,105 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
}

fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP),
sub,
sup,
);
}

fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) {
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
SubregionOrigin::RelateRegionParamBound(DUMMY_SP),
a,
b,
);
}

fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy());
}

fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
self.inner.borrow_mut().type_variables().equate(a, b);
}

fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
self.inner.borrow_mut().int_unification_table().union(a, b);
}

fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
self.inner.borrow_mut().float_unification_table().union(a, b);
}

fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
self.inner.borrow_mut().const_unification_table().union(a, b);
}

fn equate_effect_vids_raw(&self, a: rustc_type_ir::EffectVid, b: rustc_type_ir::EffectVid) {
self.inner.borrow_mut().effect_unification_table().union(a, b);
}

fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
&self,
relation: &mut R,
structurally_relate_aliases: StructurallyRelateAliases,
target_is_expected: bool,
target_vid: rustc_type_ir::TyVid,
instantiation_variance: rustc_type_ir::Variance,
source_ty: Ty<'tcx>,
) -> RelateResult<'tcx, ()> {
self.instantiate_ty_var(
relation,
structurally_relate_aliases,
target_is_expected,
target_vid,
instantiation_variance,
source_ty,
)
}

fn instantiate_int_var_raw(
&self,
vid: rustc_type_ir::IntVid,
value: rustc_type_ir::IntVarValue,
) {
self.inner.borrow_mut().int_unification_table().union_value(vid, value);
}

fn instantiate_float_var_raw(
&self,
vid: rustc_type_ir::FloatVid,
value: rustc_type_ir::FloatVarValue,
) {
self.inner.borrow_mut().float_unification_table().union_value(vid, value);
}

fn instantiate_effect_var_raw(&self, vid: rustc_type_ir::EffectVid, value: ty::Const<'tcx>) {
self.inner
.borrow_mut()
.effect_unification_table()
.union_value(vid, EffectVarValue::Known(value));
}

fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
&self,
relation: &mut R,
structurally_relate_aliases: StructurallyRelateAliases,
target_is_expected: bool,
target_vid: rustc_type_ir::ConstVid,
source_ct: ty::Const<'tcx>,
) -> RelateResult<'tcx, ()> {
self.instantiate_const_var(
relation,
structurally_relate_aliases,
target_is_expected,
target_vid,
source_ct,
)
}

fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
self.set_tainted_by_errors(e)
}
}
57 changes: 20 additions & 37 deletions compiler/rustc_infer/src/infer/relate/combine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! There are four type combiners: [TypeRelating], [Lub], and [Glb],
//! and `NllTypeRelating` in rustc_borrowck, which is only used for NLL.
//!
//! Each implements the trait [TypeRelation] and contains methods for
//! Each implements the trait [`TypeRelation`](super::TypeRelation) and contains methods for
//! combining two instances of various things and yielding a new instance.
//! These combiner methods always yield a `Result<T>`. To relate two
//! types, you can use `infcx.at(cause, param_env)` which then allows
Expand Down Expand Up @@ -134,15 +134,8 @@ impl<'tcx> InferCtxt<'tcx> {
}

(_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
match relation.structurally_relate_aliases() {
StructurallyRelateAliases::Yes => {
relate::structurally_relate_tys(relation, a, b)
}
StructurallyRelateAliases::No => {
relation.register_alias_relate_predicate(a, b);
Ok(a)
}
}
relation.register_alias_relate_predicate(a, b);
Ok(a)
}

// All other cases of inference are errors
Expand Down Expand Up @@ -215,12 +208,12 @@ impl<'tcx> InferCtxt<'tcx> {
}

(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
self.instantiate_const_var(relation, true, vid, b)?;
self.instantiate_const_var(relation, StructurallyRelateAliases::No, true, vid, b)?;
Ok(b)
}

(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
self.instantiate_const_var(relation, false, vid, a)?;
self.instantiate_const_var(relation, StructurallyRelateAliases::No, false, vid, a)?;
Ok(a)
}

Expand All @@ -235,24 +228,17 @@ impl<'tcx> InferCtxt<'tcx> {
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
if self.tcx.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 => {
relate::structurally_relate_consts(relation, a, b)
}
}
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)
}
_ => relate::structurally_relate_consts(relation, a, b),
}
Expand Down Expand Up @@ -282,19 +268,16 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.infcx.tcx
}

pub fn equate<'a>(
&'a mut self,
structurally_relate_aliases: StructurallyRelateAliases,
) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, structurally_relate_aliases, ty::Invariant)
pub fn equate<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, ty::Invariant)
}

pub fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Covariant)
TypeRelating::new(self, ty::Covariant)
}

pub fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Contravariant)
TypeRelating::new(self, ty::Contravariant)
}

pub fn lub<'a>(&'a mut self) -> Lub<'a, 'infcx, 'tcx> {
Expand Down
Loading
Loading