Make DeeplyNormalize a real type op
This commit is contained in:
parent
8c61cd4df8
commit
a02a982ffc
4 changed files with 70 additions and 37 deletions
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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;
|
||||
|
@ -27,13 +27,54 @@ where
|
|||
T::type_op_method(tcx, canonicalized)
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue