about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-06-30 10:57:17 +0200
committerlcnr <rust@lcnr.de>2023-07-03 09:12:15 +0200
commit412c6e0b0737245b029d5a3f7b1189ff7da7c7f0 (patch)
tree3b448d71749eff6ab14ec2f250d41a82a29d9cd2
parenta2dfed6711353357faf11673f145769f1f232d50 (diff)
downloadrust-412c6e0b0737245b029d5a3f7b1189ff7da7c7f0.tar.gz
rust-412c6e0b0737245b029d5a3f7b1189ff7da7c7f0.zip
review
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs8
4 files changed, 27 insertions, 16 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index d21e78e70cf..d9d91b0f6be 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -83,6 +83,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// version (resolve_vars_if_possible), this version will
     /// also select obligations if it seems useful, in an effort
     /// to get more type information.
+    // FIXME(-Ztrait-solver=next): A lot of the calls to this method should
+    // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead.
     pub(in super::super) fn resolve_vars_with_obligations(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.resolve_vars_with_obligations_and_mutate_fulfillment(ty, |_| {})
     }
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index 420a6ee8978..1084e7acfeb 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -1,7 +1,6 @@
 use crate::traits::error_reporting::TypeErrCtxtExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::{needs_normalization, TraitEngineExt as _};
-use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
+use crate::traits::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_infer::infer::at::At;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -13,22 +12,23 @@ use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
 use rustc_middle::ty::{FallibleTypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
 
+use super::FulfillmentCtxt;
+
 /// Deeply normalize all aliases in `value`. This does not handle inference and expects
 /// its input to be already fully resolved.
 pub(crate) fn deeply_normalize<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     at: At<'_, 'tcx>,
     value: T,
 ) -> Result<T, Vec<FulfillmentError<'tcx>>> {
-    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&at.infcx);
-    let mut folder =
-        NormalizationFolder { at, fulfill_cx: &mut *fulfill_cx, depth: 0, universes: Vec::new() };
+    let fulfill_cx = FulfillmentCtxt::new();
+    let mut folder = NormalizationFolder { at, fulfill_cx, depth: 0, universes: Vec::new() };
 
     value.try_fold_with(&mut folder)
 }
 
 struct NormalizationFolder<'me, 'tcx> {
     at: At<'me, 'tcx>,
-    fulfill_cx: &'me mut dyn TraitEngine<'tcx>,
+    fulfill_cx: FulfillmentCtxt<'tcx>,
     depth: usize,
     universes: Vec<Option<UniverseIndex>>,
 }
@@ -163,16 +163,14 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
             return Ok(ty);
         }
 
-        let (kind, data) = match *ty.kind() {
-            ty::Alias(kind, alias_ty) => (kind, alias_ty),
-            _ => return ty.try_super_fold_with(self),
-        };
-
         // We don't normalize opaque types unless we have
         // `Reveal::All`, even if we're in the defining scope.
-        if matches!(kind, ty::Opaque) && reveal == Reveal::UserFacing {
-            return ty.try_super_fold_with(self);
-        }
+        let data = match *ty.kind() {
+            ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => {
+                alias_ty
+            }
+            _ => return ty.try_super_fold_with(self),
+        };
 
         if data.has_escaping_bound_vars() {
             let (data, mapped_regions, mapped_types, mapped_consts) =
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 89aefc0de53..720998a51e0 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -409,7 +409,12 @@ pub fn normalize_param_env_or_error<'tcx>(
     )
 }
 
-/// Normalize a type and process all resulting obligations, returning any errors
+/// Normalize a type and process all resulting obligations, returning any errors.
+///
+/// FIXME(-Ztrait-solver=next): This should be replaced by `At::deeply_normalize`
+/// which has the same behavior with the new solver. Because using a separate
+/// fulfillment context worsens caching in the old solver, `At::deeply_normalize`
+/// is still lazy with the old solver as it otherwise negatively impacts perf.
 #[instrument(skip_all)]
 pub fn fully_normalize<'tcx, T>(
     infcx: &InferCtxt<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 56724653cb8..162e51d1fd6 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -58,12 +58,18 @@ pub trait NormalizeExt<'tcx> {
 
     /// Deeply normalizes `value`, replacing all aliases which can by normalized in
     /// the current environment. In the new solver this errors in case normalization
-    /// fails or is ambiguous. This only normalize opaque types with `Reveal::All`.
+    /// fails or is ambiguous. This only normalizes 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.
+    ///
+    /// FIXME(-Ztrait-solver=next): This has the same behavior as `traits::fully_normalize`
+    /// in the new solver, but because of performance reasons, we currently reuse an
+    /// existing fulfillment context in the old solver. Once we also eagerly prove goals with
+    /// the old solver or have removed the old solver, remove `traits::fully_normalize` and
+    /// rename this function to `At::fully_normalize`.
     fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
         self,
         value: T,