Skip to content

Commit 1f89e2a

Browse files
committed
emit AliasEq when relating type and const aliases
1 parent 23ab246 commit 1f89e2a

File tree

12 files changed

+157
-147
lines changed

12 files changed

+157
-147
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
1+
use rustc_infer::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
22
use rustc_infer::infer::NllRegionVariableOrigin;
33
use rustc_infer::traits::PredicateObligations;
44
use rustc_middle::mir::ConstraintCategory;
@@ -140,10 +140,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
140140
);
141141
}
142142

143-
fn normalization() -> NormalizationStrategy {
144-
NormalizationStrategy::Eager
145-
}
146-
147143
fn forbid_inference_vars() -> bool {
148144
true
149145
}

compiler/rustc_infer/src/infer/canonical/query_response.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::infer::canonical::{
1212
Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
1313
QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
1414
};
15-
use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
15+
use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
1616
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
1717
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
1818
use crate::traits::query::{Fallible, NoSolution};
@@ -717,10 +717,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
717717
});
718718
}
719719

720-
fn normalization() -> NormalizationStrategy {
721-
NormalizationStrategy::Eager
722-
}
723-
724720
fn forbid_inference_vars() -> bool {
725721
true
726722
}

compiler/rustc_infer/src/infer/combine.rs

+58-29
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
3838
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
3939
use rustc_middle::ty::subst::SubstsRef;
4040
use rustc_middle::ty::{
41-
self, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
42-
TypeVisitable,
41+
self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable,
42+
TypeSuperFoldable, TypeVisitable,
4343
};
4444
use rustc_middle::ty::{IntType, UintType};
4545
use rustc_span::{Span, DUMMY_SP};
@@ -74,7 +74,7 @@ impl<'tcx> InferCtxt<'tcx> {
7474
b: Ty<'tcx>,
7575
) -> RelateResult<'tcx, Ty<'tcx>>
7676
where
77-
R: TypeRelation<'tcx>,
77+
R: ObligationEmittingRelation<'tcx>,
7878
{
7979
let a_is_expected = relation.a_is_expected();
8080

@@ -122,6 +122,15 @@ impl<'tcx> InferCtxt<'tcx> {
122122
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
123123
}
124124

125+
(ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => {
126+
relation.register_type_equate_obligation(a.into(), b.into());
127+
Ok(b)
128+
}
129+
(_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => {
130+
relation.register_type_equate_obligation(b.into(), a.into());
131+
Ok(a)
132+
}
133+
125134
_ => ty::relate::super_relate_tys(relation, a, b),
126135
}
127136
}
@@ -133,7 +142,7 @@ impl<'tcx> InferCtxt<'tcx> {
133142
b: ty::Const<'tcx>,
134143
) -> RelateResult<'tcx, ty::Const<'tcx>>
135144
where
136-
R: ConstEquateRelation<'tcx>,
145+
R: ObligationEmittingRelation<'tcx>,
137146
{
138147
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
139148
if a == b {
@@ -169,15 +178,15 @@ impl<'tcx> InferCtxt<'tcx> {
169178
// FIXME(#59490): Need to remove the leak check to accommodate
170179
// escaping bound variables here.
171180
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
172-
relation.const_equate_obligation(a, b);
181+
relation.register_const_equate_obligation(a, b);
173182
}
174183
return Ok(b);
175184
}
176185
(_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => {
177186
// FIXME(#59490): Need to remove the leak check to accommodate
178187
// escaping bound variables here.
179188
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
180-
relation.const_equate_obligation(a, b);
189+
relation.register_const_equate_obligation(a, b);
181190
}
182191
return Ok(a);
183192
}
@@ -435,32 +444,21 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
435444
Ok(Generalization { ty, needs_wf })
436445
}
437446

438-
pub fn add_const_equate_obligation(
447+
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
448+
self.obligations.extend(obligations.into_iter());
449+
}
450+
451+
pub fn register_predicates(
439452
&mut self,
440-
a_is_expected: bool,
441-
a: ty::Const<'tcx>,
442-
b: ty::Const<'tcx>,
453+
obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
443454
) {
444-
let predicate = if a_is_expected {
445-
ty::PredicateKind::ConstEquate(a, b)
446-
} else {
447-
ty::PredicateKind::ConstEquate(b, a)
448-
};
449-
self.obligations.push(Obligation::new(
450-
self.tcx(),
451-
self.trace.cause.clone(),
452-
self.param_env,
453-
ty::Binder::dummy(predicate),
454-
));
455+
self.obligations.extend(obligations.into_iter().map(|to_pred| {
456+
Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred)
457+
}))
455458
}
456459

457460
pub fn mark_ambiguous(&mut self) {
458-
self.obligations.push(Obligation::new(
459-
self.tcx(),
460-
self.trace.cause.clone(),
461-
self.param_env,
462-
ty::Binder::dummy(ty::PredicateKind::Ambiguous),
463-
));
461+
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
464462
}
465463
}
466464

@@ -775,11 +773,42 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
775773
}
776774
}
777775

778-
pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> {
776+
pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
777+
/// Register obligations that must hold in order for this relation to hold
778+
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
779+
780+
/// Register predicates that must hold in order for this relation to hold. Uses
781+
/// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should
782+
/// be used if control over the obligaton causes is required.
783+
fn register_predicates(
784+
&mut self,
785+
obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
786+
);
787+
779788
/// Register an obligation that both constants must be equal to each other.
780789
///
781790
/// If they aren't equal then the relation doesn't hold.
782-
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
791+
fn register_const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
792+
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
793+
794+
self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() {
795+
ty::PredicateKind::AliasEq(a.into(), b.into())
796+
} else {
797+
ty::PredicateKind::ConstEquate(a, b)
798+
})]);
799+
}
800+
801+
/// Register an obligation that both types must be equal to each other.
802+
///
803+
/// If they aren't equal then the relation doesn't hold.
804+
fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
805+
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
806+
807+
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasEq(
808+
a.into(),
809+
b.into(),
810+
))]);
811+
}
783812
}
784813

785814
fn int_unification_error<'tcx>(

compiler/rustc_infer/src/infer/equate.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use super::combine::{CombineFields, ConstEquateRelation, RelationDir};
1+
use crate::traits::PredicateObligations;
2+
3+
use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir};
24
use super::Subtype;
35

46
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
@@ -198,8 +200,15 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
198200
}
199201
}
200202

201-
impl<'tcx> ConstEquateRelation<'tcx> for Equate<'_, '_, 'tcx> {
202-
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
203-
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
203+
impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
204+
fn register_predicates(
205+
&mut self,
206+
obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
207+
) {
208+
self.fields.register_predicates(obligations);
209+
}
210+
211+
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
212+
self.fields.register_obligations(obligations);
204213
}
205214
}

compiler/rustc_infer/src/infer/glb.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! Greatest lower bound. See [`lattice`].
22
3-
use super::combine::CombineFields;
3+
use super::combine::{CombineFields, ObligationEmittingRelation};
44
use super::lattice::{self, LatticeDir};
55
use super::InferCtxt;
66
use super::Subtype;
77

8-
use crate::infer::combine::ConstEquateRelation;
9-
use crate::traits::{ObligationCause, PredicateObligation};
8+
use crate::traits::{ObligationCause, PredicateObligations};
109
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
1110
use rustc_middle::ty::{self, Ty, TyCtxt};
1211

@@ -136,10 +135,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
136135
&self.fields.trace.cause
137136
}
138137

139-
fn add_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>) {
140-
self.fields.obligations.extend(obligations)
141-
}
142-
143138
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
144139
let mut sub = self.fields.sub(self.a_is_expected);
145140
sub.relate(v, a)?;
@@ -152,8 +147,15 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
152147
}
153148
}
154149

155-
impl<'tcx> ConstEquateRelation<'tcx> for Glb<'_, '_, 'tcx> {
156-
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
157-
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
150+
impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
151+
fn register_predicates(
152+
&mut self,
153+
obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
154+
) {
155+
self.fields.register_predicates(obligations);
156+
}
157+
158+
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
159+
self.fields.register_obligations(obligations);
158160
}
159161
}

compiler/rustc_infer/src/infer/lattice.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
//!
1818
//! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
1919
20+
use super::combine::ObligationEmittingRelation;
2021
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2122
use super::InferCtxt;
2223

23-
use crate::traits::{ObligationCause, PredicateObligation};
24-
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
24+
use crate::traits::ObligationCause;
25+
use rustc_middle::ty::relate::RelateResult;
2526
use rustc_middle::ty::TyVar;
2627
use rustc_middle::ty::{self, Ty};
2728

@@ -30,13 +31,11 @@ use rustc_middle::ty::{self, Ty};
3031
///
3132
/// GLB moves "down" the lattice (to smaller values); LUB moves
3233
/// "up" the lattice (to bigger values).
33-
pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> {
34+
pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> {
3435
fn infcx(&self) -> &'f InferCtxt<'tcx>;
3536

3637
fn cause(&self) -> &ObligationCause<'tcx>;
3738

38-
fn add_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>);
39-
4039
fn define_opaque_types(&self) -> bool;
4140

4241
// Relates the type `v` to `a` and `b` such that `v` represents
@@ -113,7 +112,7 @@ where
113112
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
114113
if this.define_opaque_types() && def_id.is_local() =>
115114
{
116-
this.add_obligations(
115+
this.register_obligations(
117116
infcx
118117
.handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
119118
.obligations,

compiler/rustc_infer/src/infer/lub.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! Least upper bound. See [`lattice`].
22
3-
use super::combine::CombineFields;
3+
use super::combine::{CombineFields, ObligationEmittingRelation};
44
use super::lattice::{self, LatticeDir};
55
use super::InferCtxt;
66
use super::Subtype;
77

8-
use crate::infer::combine::ConstEquateRelation;
9-
use crate::traits::{ObligationCause, PredicateObligation};
8+
use crate::traits::{ObligationCause, PredicateObligations};
109
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
1110
use rustc_middle::ty::{self, Ty, TyCtxt};
1211

@@ -127,12 +126,6 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
127126
}
128127
}
129128

130-
impl<'tcx> ConstEquateRelation<'tcx> for Lub<'_, '_, 'tcx> {
131-
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
132-
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
133-
}
134-
}
135-
136129
impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, 'tcx> {
137130
fn infcx(&self) -> &'infcx InferCtxt<'tcx> {
138131
self.fields.infcx
@@ -142,10 +135,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
142135
&self.fields.trace.cause
143136
}
144137

145-
fn add_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>) {
146-
self.fields.obligations.extend(obligations)
147-
}
148-
149138
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
150139
let mut sub = self.fields.sub(self.a_is_expected);
151140
sub.relate(a, v)?;
@@ -157,3 +146,16 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
157146
self.fields.define_opaque_types
158147
}
159148
}
149+
150+
impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
151+
fn register_predicates(
152+
&mut self,
153+
obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>,
154+
) {
155+
self.fields.register_predicates(obligations);
156+
}
157+
158+
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
159+
self.fields.register_obligations(obligations)
160+
}
161+
}

compiler/rustc_infer/src/infer/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub use self::LateBoundRegionConversionTime::*;
44
pub use self::RegionVariableOrigin::*;
55
pub use self::SubregionOrigin::*;
66
pub use self::ValuePairs::*;
7+
pub use combine::ObligationEmittingRelation;
78

89
use self::opaque_types::OpaqueTypeStorage;
910
pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};

0 commit comments

Comments
 (0)