about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-06-29 14:17:54 +0200
committerlcnr <rust@lcnr.de>2023-07-03 09:12:15 +0200
commita2dfed6711353357faf11673f145769f1f232d50 (patch)
treef86771e88ec9f01e8857c125dd4e5c63b9b2b45b
parent5378f07d6419bd1307e32fbba0db0c8b4e443214 (diff)
downloadrust-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.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs21
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) }
         }
     }