Skip to content

Commit 7739419

Browse files
use new solver for coherence
1 parent 59667a1 commit 7739419

File tree

13 files changed

+71
-26
lines changed

13 files changed

+71
-26
lines changed

compiler/rustc_infer/src/infer/at.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl<'tcx> InferCtxt<'tcx> {
8585
universe: self.universe.clone(),
8686
intercrate: self.intercrate,
8787
inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
88+
use_new_solver: self.use_new_solver,
8889
}
8990
}
9091
}

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@ impl<'tcx> InferCtxt<'tcx> {
121121
| (
122122
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
123123
ty::Alias(AliasKind::Projection, _),
124-
) if self.tcx.trait_solver_next() => {
124+
) if self.use_new_solver => {
125125
bug!()
126126
}
127127

128128
(_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
129-
if self.tcx.trait_solver_next() =>
129+
if self.use_new_solver =>
130130
{
131131
relation.register_type_relate_obligation(a, b);
132132
Ok(a)
@@ -242,15 +242,37 @@ impl<'tcx> InferCtxt<'tcx> {
242242
// FIXME(#59490): Need to remove the leak check to accommodate
243243
// escaping bound variables here.
244244
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
245-
relation.register_const_equate_obligation(a, b);
245+
let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
246+
247+
// FIXME(deferred_projection_equality): What do here...
248+
relation.register_predicates([ty::Binder::dummy(if self.use_new_solver {
249+
ty::PredicateKind::AliasRelate(
250+
a.into(),
251+
b.into(),
252+
ty::AliasRelationDirection::Equate,
253+
)
254+
} else {
255+
ty::PredicateKind::ConstEquate(a, b)
256+
})]);
246257
}
247258
return Ok(b);
248259
}
249260
(_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => {
250261
// FIXME(#59490): Need to remove the leak check to accommodate
251262
// escaping bound variables here.
252263
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
253-
relation.register_const_equate_obligation(a, b);
264+
let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
265+
266+
// FIXME(deferred_projection_equality): What do here...
267+
relation.register_predicates([ty::Binder::dummy(if self.use_new_solver {
268+
ty::PredicateKind::AliasRelate(
269+
a.into(),
270+
b.into(),
271+
ty::AliasRelationDirection::Equate,
272+
)
273+
} else {
274+
ty::PredicateKind::ConstEquate(a, b)
275+
})]);
254276
}
255277
return Ok(a);
256278
}
@@ -835,19 +857,6 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
835857
/// be used if control over the obligation causes is required.
836858
fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>);
837859

838-
/// Register an obligation that both constants must be equal to each other.
839-
///
840-
/// If they aren't equal then the relation doesn't hold.
841-
fn register_const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
842-
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
843-
844-
self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() {
845-
ty::PredicateKind::AliasRelate(a.into(), b.into(), ty::AliasRelationDirection::Equate)
846-
} else {
847-
ty::PredicateKind::ConstEquate(a, b)
848-
})]);
849-
}
850-
851860
/// Register an obligation that both types must be related to each other according to
852861
/// the [`ty::AliasRelationDirection`] given by [`ObligationEmittingRelation::alias_relate_direction`]
853862
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ pub struct InferCtxt<'tcx> {
347347
/// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin`
348348
/// inside non-canonicalization contexts.
349349
inside_canonicalization_ctxt: Cell<bool>,
350+
351+
pub use_new_solver: bool,
350352
}
351353

352354
/// See the `error_reporting` module for more details.
@@ -561,6 +563,8 @@ pub struct InferCtxtBuilder<'tcx> {
561563
considering_regions: bool,
562564
/// Whether we are in coherence mode.
563565
intercrate: bool,
566+
/// Whether to use the new trait solver for calls to `predicate_may_hold`, etc.
567+
use_new_solver: bool,
564568
}
565569

566570
pub trait TyCtxtInferExt<'tcx> {
@@ -574,6 +578,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
574578
defining_use_anchor: DefiningAnchor::Error,
575579
considering_regions: true,
576580
intercrate: false,
581+
use_new_solver: self.trait_solver_next(),
577582
}
578583
}
579584
}
@@ -590,6 +595,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
590595
self
591596
}
592597

598+
pub fn with_new_solver(mut self) -> Self {
599+
self.use_new_solver = true;
600+
self
601+
}
602+
593603
pub fn intercrate(mut self, intercrate: bool) -> Self {
594604
self.intercrate = intercrate;
595605
self
@@ -621,7 +631,13 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
621631
}
622632

623633
pub fn build(&mut self) -> InferCtxt<'tcx> {
624-
let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
634+
let InferCtxtBuilder {
635+
tcx,
636+
defining_use_anchor,
637+
considering_regions,
638+
intercrate,
639+
use_new_solver,
640+
} = *self;
625641
InferCtxt {
626642
tcx,
627643
defining_use_anchor,
@@ -639,6 +655,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
639655
universe: Cell::new(ty::UniverseIndex::ROOT),
640656
intercrate,
641657
inside_canonicalization_ctxt: Cell::new(false),
658+
use_new_solver,
642659
}
643660
}
644661
}

compiler/rustc_infer/src/infer/projection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl<'tcx> InferCtxt<'tcx> {
2121
recursion_depth: usize,
2222
obligations: &mut Vec<PredicateObligation<'tcx>>,
2323
) -> Ty<'tcx> {
24-
if self.tcx.trait_solver_next() {
24+
if self.use_new_solver {
2525
// FIXME(-Ztrait-solver=next): Instead of branching here,
2626
// completely change the normalization routine with the new solver.
2727
//

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
173173
};
174174
let (ref infcx, goal, var_values) = tcx
175175
.infer_ctxt()
176+
.with_new_solver()
176177
.intercrate(intercrate)
177178
.build_with_canonical(DUMMY_SP, &canonical_goal);
178179
let mut ecx = EvalCtxt {

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7272
}
7373

7474
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
75+
assert!(infcx.use_new_solver);
76+
7577
let mut errors = Vec::new();
7678
for i in 0.. {
7779
if !infcx.tcx.recursion_limit().value_within_limit(i) {

compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
5858
}
5959

6060
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
61+
assert!(!infcx.use_new_solver);
62+
6163
if !self.usable_in_snapshot {
6264
assert!(!infcx.is_in_snapshot());
6365
}

compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub fn overlapping_impls(
9898

9999
let infcx = tcx
100100
.infer_ctxt()
101+
.with_new_solver()
101102
.with_opaque_type_inference(DefiningAnchor::Bubble)
102103
.intercrate(true)
103104
.build();
@@ -113,6 +114,7 @@ pub fn overlapping_impls(
113114
// diagnostics. (These take time and can lead to false errors.)
114115
let infcx = tcx
115116
.infer_ctxt()
117+
.with_new_solver()
116118
.with_opaque_type_inference(DefiningAnchor::Bubble)
117119
.intercrate(true)
118120
.build();
@@ -299,7 +301,7 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b
299301
debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id);
300302

301303
// Create an infcx, taking the predicates of impl1 as assumptions:
302-
let infcx = tcx.infer_ctxt().build();
304+
let infcx = tcx.infer_ctxt().with_new_solver().build();
303305
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
304306
let impl_env = tcx.param_env(impl1_def_id);
305307
let subject1 = match traits::fully_normalize(

compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,21 @@ pub struct ObligationCtxt<'a, 'tcx> {
5858

5959
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
6060
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
61-
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new(infcx.tcx)) }
61+
let engine = if infcx.use_new_solver {
62+
Box::new(crate::solve::FulfillmentCtxt::new())
63+
} else {
64+
<dyn TraitEngine<'_>>::new(infcx.tcx)
65+
};
66+
Self { infcx, engine: RefCell::new(engine) }
6267
}
6368

6469
pub fn new_in_snapshot(infcx: &'a InferCtxt<'tcx>) -> Self {
65-
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new_in_snapshot(infcx.tcx)) }
70+
let engine = if infcx.use_new_solver {
71+
Box::new(crate::solve::FulfillmentCtxt::new())
72+
} else {
73+
<dyn TraitEngine<'_>>::new_in_snapshot(infcx.tcx)
74+
};
75+
Self { infcx, engine: RefCell::new(engine) }
6676
}
6777

6878
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
145145
}
146146

147147
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
148+
assert!(!infcx.use_new_solver);
148149
let selcx = SelectionContext::new(infcx);
149150
self.select(selcx)
150151
}

compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
7878
_ => obligation.param_env.without_const(),
7979
};
8080

81-
if self.tcx.trait_solver_next() {
81+
if self.use_new_solver {
8282
self.probe(|snapshot| {
8383
let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
8484
fulfill_cx.register_predicate_obligation(self, obligation.clone());

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
537537
obligation: &PredicateObligation<'tcx>,
538538
) -> Result<EvaluationResult, OverflowError> {
539539
self.evaluation_probe(|this| {
540-
if this.tcx().trait_solver_next() {
540+
if this.infcx.use_new_solver {
541541
this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])
542542
} else {
543543
this.evaluate_predicate_recursively(
@@ -583,7 +583,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
583583
where
584584
I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
585585
{
586-
if self.tcx().trait_solver_next() {
586+
if self.infcx.use_new_solver {
587587
self.evaluate_predicates_recursively_in_new_solver(predicates)
588588
} else {
589589
let mut result = EvaluatedToOk;

compiler/rustc_trait_selection/src/traits/specialize/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
152152
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity();
153153

154154
// Create an infcx, taking the predicates of impl1 as assumptions:
155-
let infcx = tcx.infer_ctxt().build();
155+
let infcx = tcx.infer_ctxt().with_new_solver().build();
156156
let impl1_trait_ref =
157157
match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) {
158158
Ok(impl1_trait_ref) => impl1_trait_ref,

0 commit comments

Comments
 (0)