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::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
|
||||||
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||||
|
use rustc_infer::traits::query::type_op::DeeplyNormalize;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
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::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
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 rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
|
@ -270,20 +267,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||||
ConstraintCategory<'tcx>,
|
ConstraintCategory<'tcx>,
|
||||||
)>,
|
)>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let result = CustomTypeOp::new(
|
match self.param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, self.span)
|
||||||
|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 {
|
|
||||||
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
|
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
|
||||||
if let Some(QueryRegionConstraints { outlives }) = constraints {
|
if let Some(QueryRegionConstraints { outlives }) = constraints {
|
||||||
next_outlives_predicates.extend(outlives.iter().copied());
|
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::outlives::env::RegionBoundPairs;
|
||||||
use rustc_infer::infer::region_constraints::GenericKind;
|
use rustc_infer::infer::region_constraints::GenericKind;
|
||||||
use rustc_infer::infer::{InferCtxt, outlives};
|
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::mir::ConstraintCategory;
|
||||||
use rustc_middle::traits::ObligationCause;
|
|
||||||
use rustc_middle::traits::query::OutlivesBound;
|
use rustc_middle::traits::query::OutlivesBound;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
|
||||||
use rustc_span::{ErrorGuaranteed, Span};
|
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 rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
use type_op::TypeOpOutput;
|
use type_op::TypeOpOutput;
|
||||||
|
@ -360,18 +357,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||||
output: normalized_outlives,
|
output: normalized_outlives,
|
||||||
constraints: constraints_normalize,
|
constraints: constraints_normalize,
|
||||||
error_info: _,
|
error_info: _,
|
||||||
}) = CustomTypeOp::new(
|
}) = self
|
||||||
|ocx| {
|
.param_env
|
||||||
ocx.deeply_normalize(
|
.and(DeeplyNormalize { value: outlives })
|
||||||
&ObligationCause::dummy_with_span(span),
|
.fully_perform(self.infcx, span)
|
||||||
self.param_env,
|
|
||||||
outlives,
|
|
||||||
)
|
|
||||||
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
|
|
||||||
},
|
|
||||||
"normalize type outlives obligation",
|
|
||||||
)
|
|
||||||
.fully_perform(self.infcx, span)
|
|
||||||
else {
|
else {
|
||||||
self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
|
self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -41,11 +41,18 @@ pub mod type_op {
|
||||||
pub predicate: Predicate<'tcx>,
|
pub predicate: Predicate<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Normalizes, but not in the new solver.
|
||||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct Normalize<T> {
|
pub struct Normalize<T> {
|
||||||
pub value: 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)]
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct ImpliedOutlivesBounds<'tcx> {
|
pub struct ImpliedOutlivesBounds<'tcx> {
|
||||||
pub ty: Ty<'tcx>,
|
pub ty: Ty<'tcx>,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt;
|
||||||
|
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
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::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -27,13 +27,54 @@ where
|
||||||
T::type_op_method(tcx, canonicalized)
|
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(
|
fn perform_locally_with_next_solver(
|
||||||
ocx: &ObligationCtxt<'_, 'tcx>,
|
ocx: &ObligationCtxt<'_, 'tcx>,
|
||||||
key: ParamEnvAnd<'tcx, Self>,
|
key: ParamEnvAnd<'tcx, Self>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<Self::QueryResponse, NoSolution> {
|
) -> Result<Self::QueryResponse, NoSolution> {
|
||||||
// FIXME(-Znext-solver): shouldn't be using old normalizer
|
ocx.deeply_normalize(
|
||||||
Ok(ocx.normalize(&ObligationCause::dummy_with_span(span), key.param_env, key.value.value))
|
&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)
|
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