emit AliasEq
when relating type and const aliases
This commit is contained in:
parent
23ab2464be
commit
1f89e2aef2
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<Item = impl ToPredicate<'tcx>>,
|
||||
) {
|
||||
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<Item = impl ToPredicate<'tcx>>,
|
||||
);
|
||||
|
||||
/// 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>(
|
||||
|
@ -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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
self.fields.register_predicates(obligations);
|
||||
}
|
||||
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.fields.register_obligations(obligations);
|
||||
}
|
||||
}
|
||||
|
@ -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<PredicateObligation<'tcx>>) {
|
||||
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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
self.fields.register_predicates(obligations);
|
||||
}
|
||||
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.fields.register_obligations(obligations);
|
||||
}
|
||||
}
|
||||
|
@ -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<PredicateObligation<'tcx>>);
|
||||
|
||||
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,
|
||||
|
@ -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<PredicateObligation<'tcx>>) {
|
||||
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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
self.fields.register_predicates(obligations);
|
||||
}
|
||||
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.fields.register_obligations(obligations)
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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<PredicateObligation<'tcx>>);
|
||||
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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
self.fields.register_predicates(obligations);
|
||||
}
|
||||
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.fields.register_obligations(obligations);
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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<Item = impl ty::ToPredicate<'tcx>>,
|
||||
) {
|
||||
// FIXME(deferred_projection_equality)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user