diff options
| author | lcnr <rust@lcnr.de> | 2023-06-29 14:17:54 +0200 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2023-07-03 09:12:15 +0200 |
| commit | a2dfed6711353357faf11673f145769f1f232d50 (patch) | |
| tree | f86771e88ec9f01e8857c125dd4e5c63b9b2b45b | |
| parent | 5378f07d6419bd1307e32fbba0db0c8b4e443214 (diff) | |
| download | rust-a2dfed6711353357faf11673f145769f1f232d50.tar.gz rust-a2dfed6711353357faf11673f145769f1f232d50.zip | |
`deeply_normalize` pass in fulfill cx for old solver
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/engine.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 21 |
2 files changed, 15 insertions, 12 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 2fa69b995ff..19dd4ce06b0 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -229,7 +229,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // implied_bounds.insert(ty); let cause = ObligationCause::misc(span, def_id); - match self.infcx.at(&cause, param_env).deeply_normalize(ty) { + match self + .infcx + .at(&cause, param_env) + .deeply_normalize(ty, &mut **self.engine.borrow_mut()) + { // Insert well-formed types, ignoring duplicates. Ok(normalized) => drop(implied_bounds.insert(normalized)), Err(normalization_errors) => errors.extend(normalization_errors), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e4eea14ef74..56724653cb8 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -20,7 +20,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::select::ProjectionMatchesProjection; -use crate::traits::TraitEngineExt as _; use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; @@ -32,7 +31,6 @@ use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::FulfillmentError; use rustc_infer::traits::ObligationCauseCode; use rustc_infer::traits::TraitEngine; -use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; @@ -59,17 +57,17 @@ pub trait NormalizeExt<'tcx> { fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>; /// Deeply normalizes `value`, replacing all aliases which can by normalized in - /// the current environment. Unlike other normalization routines, this errors - /// in case normalization fails or is ambiguous. + /// the current environment. In the new solver this errors in case normalization + /// fails or is ambiguous. This only normalize opaque types with `Reveal::All`. /// - /// In the old solver this simply uses `normalize` and errors in - /// case of ambiguity. The new solver only normalizes in this function and - /// `normalize` is a noop. - /// - /// This only normalize opaque types with `Reveal::All`. + /// In the old solver this simply uses `normalizes` and adds the nested obligations + /// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the + /// same goals in both a temporary and the shared context which negatively impacts + /// performance as these don't share caching. fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: T, + fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<T, Vec<FulfillmentError<'tcx>>>; } @@ -88,15 +86,16 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> { fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: T, + fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<T, Vec<FulfillmentError<'tcx>>> { if self.infcx.next_trait_solver() { crate::solve::deeply_normalize(self, value) } else { - let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&self.infcx); let value = self .normalize(value) .into_value_registering_obligations(self.infcx, &mut *fulfill_cx); - let errors = fulfill_cx.select_all_or_error(self.infcx); + let errors = fulfill_cx.select_where_possible(self.infcx); + let value = self.infcx.resolve_vars_if_possible(value); if errors.is_empty() { Ok(value) } else { Err(errors) } } } |
