diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-25 21:27:06 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-02-11 19:24:07 +0000 |
| commit | a02a982ffc73457caa1849b09da63e84f78541c6 (patch) | |
| tree | 8b06aae1c0b9638b1646525f77ed69caffe8fe95 | |
| parent | 8c61cd4df8434573190336b8f16169f3c2b22a7a (diff) | |
| download | rust-a02a982ffc73457caa1849b09da63e84f78541c6.tar.gz rust-a02a982ffc73457caa1849b09da63e84f78541c6.zip | |
Make DeeplyNormalize a real type op
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") + } +} |
