Deeply normalize signature in new solver
This commit is contained in:
parent
ef9d992a0d
commit
d5be3bae51
8 changed files with 129 additions and 9 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue