Skip to content

Commit a2dfed6

Browse files
committed
deeply_normalize pass in fulfill cx for old solver
1 parent 5378f07 commit a2dfed6

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

compiler/rustc_trait_selection/src/traits/engine.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
229229

230230
// implied_bounds.insert(ty);
231231
let cause = ObligationCause::misc(span, def_id);
232-
match self.infcx.at(&cause, param_env).deeply_normalize(ty) {
232+
match self
233+
.infcx
234+
.at(&cause, param_env)
235+
.deeply_normalize(ty, &mut **self.engine.borrow_mut())
236+
{
233237
// Insert well-formed types, ignoring duplicates.
234238
Ok(normalized) => drop(implied_bounds.insert(normalized)),
235239
Err(normalization_errors) => errors.extend(normalization_errors),

compiler/rustc_trait_selection/src/traits/project.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
2020
use crate::traits::error_reporting::TypeErrCtxtExt as _;
2121
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
2222
use crate::traits::select::ProjectionMatchesProjection;
23-
use crate::traits::TraitEngineExt as _;
2423
use rustc_data_structures::sso::SsoHashSet;
2524
use rustc_data_structures::stack::ensure_sufficient_stack;
2625
use rustc_errors::ErrorGuaranteed;
@@ -32,7 +31,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
3231
use rustc_infer::traits::FulfillmentError;
3332
use rustc_infer::traits::ObligationCauseCode;
3433
use rustc_infer::traits::TraitEngine;
35-
use rustc_infer::traits::TraitEngineExt as _;
3634
use rustc_middle::traits::select::OverflowError;
3735
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
3836
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
@@ -59,17 +57,17 @@ pub trait NormalizeExt<'tcx> {
5957
fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
6058

6159
/// Deeply normalizes `value`, replacing all aliases which can by normalized in
62-
/// the current environment. Unlike other normalization routines, this errors
63-
/// in case normalization fails or is ambiguous.
60+
/// the current environment. In the new solver this errors in case normalization
61+
/// fails or is ambiguous. This only normalize opaque types with `Reveal::All`.
6462
///
65-
/// In the old solver this simply uses `normalize` and errors in
66-
/// case of ambiguity. The new solver only normalizes in this function and
67-
/// `normalize` is a noop.
68-
///
69-
/// This only normalize opaque types with `Reveal::All`.
63+
/// In the old solver this simply uses `normalizes` and adds the nested obligations
64+
/// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the
65+
/// same goals in both a temporary and the shared context which negatively impacts
66+
/// performance as these don't share caching.
7067
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
7168
self,
7269
value: T,
70+
fulfill_cx: &mut dyn TraitEngine<'tcx>,
7371
) -> Result<T, Vec<FulfillmentError<'tcx>>>;
7472
}
7573

@@ -88,15 +86,16 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
8886
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
8987
self,
9088
value: T,
89+
fulfill_cx: &mut dyn TraitEngine<'tcx>,
9190
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
9291
if self.infcx.next_trait_solver() {
9392
crate::solve::deeply_normalize(self, value)
9493
} else {
95-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&self.infcx);
9694
let value = self
9795
.normalize(value)
9896
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
99-
let errors = fulfill_cx.select_all_or_error(self.infcx);
97+
let errors = fulfill_cx.select_where_possible(self.infcx);
98+
let value = self.infcx.resolve_vars_if_possible(value);
10099
if errors.is_empty() { Ok(value) } else { Err(errors) }
101100
}
102101
}

0 commit comments

Comments
 (0)