1
Fork 0

ImpliedOutlivesBounds to rustc_middle

This commit is contained in:
lcnr 2024-10-15 18:03:25 +02:00
parent 06d261daf6
commit 401f9b4e0a
6 changed files with 27 additions and 29 deletions

View file

@ -373,7 +373,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
) -> Option<&'tcx QueryRegionConstraints<'tcx>> { ) -> Option<&'tcx QueryRegionConstraints<'tcx>> {
let TypeOpOutput { output: bounds, constraints, .. } = self let TypeOpOutput { output: bounds, constraints, .. } = self
.param_env .param_env
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) .and(type_op::ImpliedOutlivesBounds { ty })
.fully_perform(self.infcx, span) .fully_perform(self.infcx, span)
.map_err(|_: ErrorGuaranteed| debug!("failed to compute implied bounds {:?}", ty)) .map_err(|_: ErrorGuaranteed| debug!("failed to compute implied bounds {:?}", ty))
.ok()?; .ok()?;

View file

@ -65,8 +65,8 @@ use crate::query::plumbing::{
CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at, CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
}; };
use crate::traits::query::{ use crate::traits::query::{
CanonicalAliasGoal, CanonicalPredicateGoal, CanonicalTyGoal, CanonicalAliasGoal, CanonicalImpliedOutlivesBoundsGoal, CanonicalPredicateGoal,
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal,
CanonicalTypeOpProvePredicateGoal, DropckConstraint, DropckOutlivesResult, CanonicalTypeOpProvePredicateGoal, DropckConstraint, DropckOutlivesResult,
MethodAutoderefStepsResult, NoSolution, NormalizationResult, OutlivesBound, MethodAutoderefStepsResult, NoSolution, NormalizationResult, OutlivesBound,
}; };
@ -2049,21 +2049,21 @@ rustc_queries! {
} }
query implied_outlives_bounds_compat( query implied_outlives_bounds_compat(
goal: CanonicalTyGoal<'tcx> goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>
) -> Result< ) -> Result<
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
NoSolution, NoSolution,
> { > {
desc { "computing implied outlives bounds for `{}`", goal.value.value } desc { "computing implied outlives bounds for `{}`", goal.value.value.ty }
} }
query implied_outlives_bounds( query implied_outlives_bounds(
goal: CanonicalTyGoal<'tcx> goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>
) -> Result< ) -> Result<
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
NoSolution, NoSolution,
> { > {
desc { "computing implied outlives bounds v2 for `{}`", goal.value.value } desc { "computing implied outlives bounds v2 for `{}`", goal.value.value.ty }
} }
/// Do not call this query directly: /// Do not call this query directly:

View file

@ -70,6 +70,11 @@ pub mod type_op {
Self { value } Self { value }
} }
} }
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
pub struct ImpliedOutlivesBounds<'tcx> {
pub ty: Ty<'tcx>,
}
} }
pub type CanonicalAliasGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; pub type CanonicalAliasGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
@ -92,6 +97,9 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>; Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
pub type CanonicalImpliedOutlivesBoundsGoal<'tcx> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ImpliedOutlivesBounds<'tcx>>>;
#[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)] #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)]
pub struct DropckOutlivesResult<'tcx> { pub struct DropckOutlivesResult<'tcx> {
pub kinds: Vec<GenericArg<'tcx>>, pub kinds: Vec<GenericArg<'tcx>>,

View file

@ -1,6 +1,7 @@
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_infer::infer::InferOk; use rustc_infer::infer::InferOk;
use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
use rustc_macros::extension; use rustc_macros::extension;
use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints};
use rustc_middle::span_bug; use rustc_middle::span_bug;
@ -54,11 +55,12 @@ fn implied_outlives_bounds<'a, 'tcx>(
assert!(!ty.has_non_region_infer()); assert!(!ty.has_non_region_infer());
let mut canonical_var_values = OriginalQueryValues::default(); let mut canonical_var_values = OriginalQueryValues::default();
let canonical_ty = infcx.canonicalize_query(param_env.and(ty), &mut canonical_var_values); let input = ImpliedOutlivesBounds { ty };
let canonical = infcx.canonicalize_query(param_env.and(input), &mut canonical_var_values);
let implied_bounds_result = if compat { let implied_bounds_result = if compat {
infcx.tcx.implied_outlives_bounds_compat(canonical_ty) infcx.tcx.implied_outlives_bounds_compat(canonical)
} else { } else {
infcx.tcx.implied_outlives_bounds(canonical_ty) infcx.tcx.implied_outlives_bounds(canonical)
}; };
let Ok(canonical_result) = implied_bounds_result else { let Ok(canonical_result) = implied_bounds_result else {
return vec![]; return vec![];

View file

@ -1,7 +1,7 @@
use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::query::OutlivesBound;
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::infer::canonical::CanonicalQueryResponse;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
@ -14,11 +14,6 @@ use tracing::debug;
use crate::traits::query::NoSolution; use crate::traits::query::NoSolution;
use crate::traits::{ObligationCtxt, wf}; use crate::traits::{ObligationCtxt, wf};
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable)]
pub struct ImpliedOutlivesBounds<'tcx> {
pub ty: Ty<'tcx>,
}
impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
type QueryResponse = Vec<OutlivesBound<'tcx>>; type QueryResponse = Vec<OutlivesBound<'tcx>>;
@ -40,14 +35,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> { ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
// FIXME this `unchecked_map` is only necessary because the
// query is defined as taking a `ParamEnvAnd<Ty>`; it should
// take an `ImpliedOutlivesBounds` instead
let canonicalized = canonicalized.unchecked_map(|ParamEnvAnd { param_env, value }| {
let ImpliedOutlivesBounds { ty } = value;
param_env.and(ty)
});
if tcx.sess.opts.unstable_opts.no_implied_bounds_compat { if tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
tcx.implied_outlives_bounds(canonicalized) tcx.implied_outlives_bounds(canonicalized)
} else { } else {

View file

@ -5,13 +5,14 @@
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::canonical::{self, Canonical}; use rustc_infer::infer::canonical::{self, Canonical};
use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::query::OutlivesBound;
use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{ use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{
compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner, compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner,
}; };
use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; use rustc_trait_selection::traits::query::{CanonicalImpliedOutlivesBoundsGoal, NoSolution};
pub(crate) fn provide(p: &mut Providers) { pub(crate) fn provide(p: &mut Providers) {
*p = Providers { implied_outlives_bounds_compat, ..*p }; *p = Providers { implied_outlives_bounds_compat, ..*p };
@ -20,26 +21,26 @@ pub(crate) fn provide(p: &mut Providers) {
fn implied_outlives_bounds_compat<'tcx>( fn implied_outlives_bounds_compat<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
goal: CanonicalTyGoal<'tcx>, goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>,
) -> Result< ) -> Result<
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
NoSolution, NoSolution,
> { > {
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
let (param_env, ty) = key.into_parts(); let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty) compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty)
}) })
} }
fn implied_outlives_bounds<'tcx>( fn implied_outlives_bounds<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
goal: CanonicalTyGoal<'tcx>, goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>,
) -> Result< ) -> Result<
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
NoSolution, NoSolution,
> { > {
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
let (param_env, ty) = key.into_parts(); let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
compute_implied_outlives_bounds_inner(ocx, param_env, ty) compute_implied_outlives_bounds_inner(ocx, param_env, ty)
}) })
} }