diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-25 22:22:53 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-02-11 19:24:07 +0000 |
| commit | d5be3bae5182ad064bf2b28a7c9d6847e08d8463 (patch) | |
| tree | ea7e7659afe55546848db283655db80810881425 /compiler | |
| parent | ef9d992a0d8a7a093a398e51b42dbea8eed72847 (diff) | |
| download | rust-d5be3bae5182ad064bf2b28a7c9d6847e08d8463.tar.gz rust-d5be3bae5182ad064bf2b28a7c9d6847e08d8463.zip | |
Deeply normalize signature in new solver
Diffstat (limited to 'compiler')
5 files changed, 75 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 30b0a358580..aa968a1e40f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -9,8 +9,8 @@ use rustc_infer::infer::{ }; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::query::{ - CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, - CanonicalTypeOpProvePredicateGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpDeeplyNormalizeGoal, + CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ @@ -109,6 +109,14 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUnivers } } +impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUniverseInfo<'tcx> + for CanonicalTypeOpDeeplyNormalizeGoal<'tcx, T> +{ + fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { + UniverseInfo::TypeOp(Rc::new(DeeplyNormalizeQuery { canonical_query: self, base_universe })) + } +} + impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpAscribeUserTypeGoal<'tcx> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { UniverseInfo::TypeOp(Rc::new(AscribeUserTypeQuery { canonical_query: self, base_universe })) @@ -285,6 +293,53 @@ where } } +struct DeeplyNormalizeQuery<'tcx, T> { + canonical_query: CanonicalTypeOpDeeplyNormalizeGoal<'tcx, T>, + base_universe: ty::UniverseIndex, +} + +impl<'tcx, T> TypeOpInfo<'tcx> for DeeplyNormalizeQuery<'tcx, T> +where + T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx, +{ + fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> { + tcx.dcx().create_err(HigherRankedLifetimeError { + cause: Some(HigherRankedErrorCause::CouldNotNormalize { + value: self.canonical_query.canonical.value.value.value.to_string(), + }), + span, + }) + } + + fn base_universe(&self) -> ty::UniverseIndex { + self.base_universe + } + + fn nice_error<'infcx>( + &self, + mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>, + cause: ObligationCause<'tcx>, + placeholder_region: ty::Region<'tcx>, + error_region: Option<ty::Region<'tcx>>, + ) -> Option<Diag<'infcx>> { + let (infcx, key, _) = + mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); + let ocx = ObligationCtxt::new(&infcx); + + let (param_env, value) = key.into_parts(); + let _ = ocx.deeply_normalize(&cause, param_env, value.value); + + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) + } +} + struct AscribeUserTypeQuery<'tcx> { canonical_query: CanonicalTypeOpAscribeUserTypeGoal<'tcx>, base_universe: ty::UniverseIndex, diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index bffd9f38334..b3fa786a517 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -149,6 +149,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.normalize_with_category(value, location, ConstraintCategory::Boring) } + pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T + where + T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, + { + let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + self.infcx.param_env.and(type_op::normalize::DeeplyNormalize { value }), + ); + result.unwrap_or(value) + } + #[instrument(skip(self), level = "debug")] pub(super) fn normalize_with_category<T>( &mut self, 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 b8008f18a39..efbae1e1535 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -300,9 +300,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Add implied bounds from impl header. if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) { for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) { - let result: Result<_, ErrorGuaranteed> = param_env - .and(DeeplyNormalize { value: ty }) - .fully_perform(self.infcx, span); + let result: Result<_, ErrorGuaranteed> = + param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, span); let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else { continue; }; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 26a5d438edb..93081919ec7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1116,7 +1116,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring, ); - let sig = self.normalize(unnormalized_sig, term_location); + let sig = self.deeply_normalize(unnormalized_sig, term_location); // HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))` // with built-in `Fn` implementations, since the impl may not be // well-formed itself. diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 5b19d1742cd..4203c8fd861 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -87,6 +87,9 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>; +pub type CanonicalTypeOpDeeplyNormalizeGoal<'tcx, T> = + CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::DeeplyNormalize<T>>>; + pub type CanonicalImpliedOutlivesBoundsGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>; |
