about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-25 21:27:06 +0000
committerMichael Goulet <michael@errs.io>2025-02-11 19:24:07 +0000
commita02a982ffc73457caa1849b09da63e84f78541c6 (patch)
tree8b06aae1c0b9638b1646525f77ed69caffe8fe95
parent8c61cd4df8434573190336b8f16169f3c2b22a7a (diff)
downloadrust-a02a982ffc73457caa1849b09da63e84f78541c6.tar.gz
rust-a02a982ffc73457caa1849b09da63e84f78541c6.zip
Make DeeplyNormalize a real type op
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs21
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs21
-rw-r--r--compiler/rustc_middle/src/traits/query.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs58
4 files changed, 70 insertions, 37 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 4b7f5321388..3b48ca305c4 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -4,15 +4,12 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
 use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
+use rustc_infer::traits::query::type_op::DeeplyNormalize;
 use rustc_middle::bug;
 use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
-use rustc_middle::traits::ObligationCause;
-use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::fold::fold_regions;
 use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_span::Span;
-use rustc_trait_selection::traits::ScrubbedTraitError;
-use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
 use tracing::{debug, instrument};
 
@@ -270,20 +267,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             ConstraintCategory<'tcx>,
         )>,
     ) -> Ty<'tcx> {
-        let result = CustomTypeOp::new(
-            |ocx| {
-                ocx.deeply_normalize(
-                    &ObligationCause::dummy_with_span(self.span),
-                    self.param_env,
-                    ty,
-                )
-                .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
-            },
-            "normalize type outlives obligation",
-        )
-        .fully_perform(self.infcx, self.span);
-
-        match result {
+        match self.param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, self.span)
+        {
             Ok(TypeOpOutput { output: ty, constraints, .. }) => {
                 if let Some(QueryRegionConstraints { outlives }) = constraints {
                     next_outlives_predicates.extend(outlives.iter().copied());
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index edf612f4e97..2bac084c964 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -5,14 +5,11 @@ use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::{InferCtxt, outlives};
-use rustc_infer::traits::ScrubbedTraitError;
+use rustc_infer::traits::query::type_op::DeeplyNormalize;
 use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::query::OutlivesBound;
 use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, Span};
-use rustc_trait_selection::solve::NoSolution;
-use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use tracing::{debug, instrument};
 use type_op::TypeOpOutput;
@@ -360,18 +357,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 output: normalized_outlives,
                 constraints: constraints_normalize,
                 error_info: _,
-            }) = CustomTypeOp::new(
-                |ocx| {
-                    ocx.deeply_normalize(
-                        &ObligationCause::dummy_with_span(span),
-                        self.param_env,
-                        outlives,
-                    )
-                    .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
-                },
-                "normalize type outlives obligation",
-            )
-            .fully_perform(self.infcx, span)
+            }) = self
+                .param_env
+                .and(DeeplyNormalize { value: outlives })
+                .fully_perform(self.infcx, span)
             else {
                 self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
                 return;
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 8cd04a6f5e4..5b19d1742cd 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -41,11 +41,18 @@ pub mod type_op {
         pub predicate: Predicate<'tcx>,
     }
 
+    /// Normalizes, but not in the new solver.
     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
     pub struct Normalize<T> {
         pub value: T,
     }
 
+    /// Normalizes, and deeply normalizes in the new solver.
+    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
+    pub struct DeeplyNormalize<T> {
+        pub value: T,
+    }
+
     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
     pub struct ImpliedOutlivesBounds<'tcx> {
         pub ty: Ty<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
index e8c2528aa6e..2f6bbd7f4cf 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
@@ -2,7 +2,7 @@ use std::fmt;
 
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::query::NoSolution;
-pub use rustc_middle::traits::query::type_op::Normalize;
+pub use rustc_middle::traits::query::type_op::{DeeplyNormalize, Normalize};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
@@ -28,12 +28,53 @@ where
     }
 
     fn perform_locally_with_next_solver(
+        _ocx: &ObligationCtxt<'_, 'tcx>,
+        key: ParamEnvAnd<'tcx, Self>,
+        _span: Span,
+    ) -> Result<Self::QueryResponse, NoSolution> {
+        Ok(key.value.value)
+    }
+}
+
+impl<'tcx, T> super::QueryTypeOp<'tcx> for DeeplyNormalize<T>
+where
+    T: Normalizable<'tcx> + 'tcx,
+{
+    type QueryResponse = T;
+
+    fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
+        if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
+    }
+
+    fn perform_query(
+        tcx: TyCtxt<'tcx>,
+        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
+        T::type_op_method(
+            tcx,
+            CanonicalQueryInput {
+                typing_mode: canonicalized.typing_mode,
+                canonical: canonicalized.canonical.unchecked_map(
+                    |ty::ParamEnvAnd { param_env, value }| ty::ParamEnvAnd {
+                        param_env,
+                        value: Normalize { value: value.value },
+                    },
+                ),
+            },
+        )
+    }
+
+    fn perform_locally_with_next_solver(
         ocx: &ObligationCtxt<'_, 'tcx>,
         key: ParamEnvAnd<'tcx, Self>,
         span: Span,
     ) -> Result<Self::QueryResponse, NoSolution> {
-        // FIXME(-Znext-solver): shouldn't be using old normalizer
-        Ok(ocx.normalize(&ObligationCause::dummy_with_span(span), key.param_env, key.value.value))
+        ocx.deeply_normalize(
+            &ObligationCause::dummy_with_span(span),
+            key.param_env,
+            key.value.value,
+        )
+        .map_err(|_| NoSolution)
     }
 }
 
@@ -81,3 +122,14 @@ impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
         tcx.type_op_normalize_fn_sig(canonicalized)
     }
 }
+
+/// This impl is not needed, since we never normalize type outlives predicates
+/// in the old solver, but is required by trait bounds to be happy.
+impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
+    fn type_op_method(
+        _tcx: TyCtxt<'tcx>,
+        _canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
+        unreachable!("we never normalize PolyTypeOutlivesPredicate")
+    }
+}