Skip to content

Commit 1623ab0

Browse files
committed
Auto merge of rust-lang#107507 - BoxyUwU:deferred_projection_equality, r=lcnr
Implement `deferred_projection_equality` for erica solver Somewhat of a revival of rust-lang#96912. When relating projections now emit an `AliasEq` obligation instead of attempting to determine equality of projections that may not be as normalized as possible (i.e. because of lazy norm, or just containing inference variables that prevent us from resolving an impl). Only do this when the new solver is enabled
2 parents 5a8dfd9 + 4c98429 commit 1623ab0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+585
-163
lines changed

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 1 addition & 5 deletions
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_hir_analysis/src/astconv/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13201320
ty::Clause::RegionOutlives(_) => bug!(),
13211321
},
13221322
ty::PredicateKind::WellFormed(_)
1323+
| ty::PredicateKind::AliasEq(..)
13231324
| ty::PredicateKind::ObjectSafe(_)
13241325
| ty::PredicateKind::ClosureKind(_, _, _)
13251326
| ty::PredicateKind::Subtype(_)

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>(
517517
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_))
518518
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
519519
| ty::PredicateKind::Clause(ty::Clause::Projection(_))
520+
| ty::PredicateKind::AliasEq(..)
520521
| ty::PredicateKind::WellFormed(_)
521522
| ty::PredicateKind::Subtype(_)
522523
| ty::PredicateKind::Coerce(_)

compiler/rustc_hir_analysis/src/outlives/explicit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
5555
ty::PredicateKind::Clause(ty::Clause::Trait(..))
5656
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
5757
| ty::PredicateKind::WellFormed(..)
58+
| ty::PredicateKind::AliasEq(..)
5859
| ty::PredicateKind::ObjectSafe(..)
5960
| ty::PredicateKind::ClosureKind(..)
6061
| ty::PredicateKind::Subtype(..)

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669669
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
670670
| ty::PredicateKind::WellFormed(..)
671671
| ty::PredicateKind::ObjectSafe(..)
672+
| ty::PredicateKind::AliasEq(..)
672673
| ty::PredicateKind::ConstEvaluatable(..)
673674
| ty::PredicateKind::ConstEquate(..)
674675
// N.B., this predicate is created by breaking down a

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
837837
| ty::PredicateKind::ConstEvaluatable(..)
838838
| ty::PredicateKind::ConstEquate(..)
839839
| ty::PredicateKind::Ambiguous
840+
| ty::PredicateKind::AliasEq(..)
840841
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
841842
}
842843
});

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

Lines changed: 1 addition & 5 deletions
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

Lines changed: 58 additions & 29 deletions
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

@@ -779,11 +777,42 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
779777
}
780778
}
781779

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

789818
fn int_unification_error<'tcx>(

compiler/rustc_infer/src/infer/equate.rs

Lines changed: 13 additions & 4 deletions
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

Lines changed: 12 additions & 10 deletions
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
}

0 commit comments

Comments
 (0)