Skip to content

Commit a02a982

Browse files
Make DeeplyNormalize a real type op
1 parent 8c61cd4 commit a02a982

File tree

4 files changed

+70
-37
lines changed

4 files changed

+70
-37
lines changed

Diff for: compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
44
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
55
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
66
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
7+
use rustc_infer::traits::query::type_op::DeeplyNormalize;
78
use rustc_middle::bug;
89
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
9-
use rustc_middle::traits::ObligationCause;
10-
use rustc_middle::traits::query::NoSolution;
1110
use rustc_middle::ty::fold::fold_regions;
1211
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
1312
use rustc_span::Span;
14-
use rustc_trait_selection::traits::ScrubbedTraitError;
15-
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1613
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
1714
use tracing::{debug, instrument};
1815

@@ -270,20 +267,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
270267
ConstraintCategory<'tcx>,
271268
)>,
272269
) -> Ty<'tcx> {
273-
let result = CustomTypeOp::new(
274-
|ocx| {
275-
ocx.deeply_normalize(
276-
&ObligationCause::dummy_with_span(self.span),
277-
self.param_env,
278-
ty,
279-
)
280-
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
281-
},
282-
"normalize type outlives obligation",
283-
)
284-
.fully_perform(self.infcx, self.span);
285-
286-
match result {
270+
match self.param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, self.span)
271+
{
287272
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
288273
if let Some(QueryRegionConstraints { outlives }) = constraints {
289274
next_outlives_predicates.extend(outlives.iter().copied());

Diff for: compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@ use rustc_infer::infer::canonical::QueryRegionConstraints;
55
use rustc_infer::infer::outlives::env::RegionBoundPairs;
66
use rustc_infer::infer::region_constraints::GenericKind;
77
use rustc_infer::infer::{InferCtxt, outlives};
8-
use rustc_infer::traits::ScrubbedTraitError;
8+
use rustc_infer::traits::query::type_op::DeeplyNormalize;
99
use rustc_middle::mir::ConstraintCategory;
10-
use rustc_middle::traits::ObligationCause;
1110
use rustc_middle::traits::query::OutlivesBound;
1211
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
1312
use rustc_span::{ErrorGuaranteed, Span};
14-
use rustc_trait_selection::solve::NoSolution;
15-
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1613
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1714
use tracing::{debug, instrument};
1815
use type_op::TypeOpOutput;
@@ -360,18 +357,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
360357
output: normalized_outlives,
361358
constraints: constraints_normalize,
362359
error_info: _,
363-
}) = CustomTypeOp::new(
364-
|ocx| {
365-
ocx.deeply_normalize(
366-
&ObligationCause::dummy_with_span(span),
367-
self.param_env,
368-
outlives,
369-
)
370-
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
371-
},
372-
"normalize type outlives obligation",
373-
)
374-
.fully_perform(self.infcx, span)
360+
}) = self
361+
.param_env
362+
.and(DeeplyNormalize { value: outlives })
363+
.fully_perform(self.infcx, span)
375364
else {
376365
self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
377366
return;

Diff for: compiler/rustc_middle/src/traits/query.rs

+7
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,18 @@ pub mod type_op {
4141
pub predicate: Predicate<'tcx>,
4242
}
4343

44+
/// Normalizes, but not in the new solver.
4445
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
4546
pub struct Normalize<T> {
4647
pub value: T,
4748
}
4849

50+
/// Normalizes, and deeply normalizes in the new solver.
51+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
52+
pub struct DeeplyNormalize<T> {
53+
pub value: T,
54+
}
55+
4956
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
5057
pub struct ImpliedOutlivesBounds<'tcx> {
5158
pub ty: Ty<'tcx>,

Diff for: compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs

+55-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt;
22

33
use rustc_middle::traits::ObligationCause;
44
use rustc_middle::traits::query::NoSolution;
5-
pub use rustc_middle::traits::query::type_op::Normalize;
5+
pub use rustc_middle::traits::query::type_op::{DeeplyNormalize, Normalize};
66
use rustc_middle::ty::fold::TypeFoldable;
77
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
88
use rustc_span::Span;
@@ -27,13 +27,54 @@ where
2727
T::type_op_method(tcx, canonicalized)
2828
}
2929

30+
fn perform_locally_with_next_solver(
31+
_ocx: &ObligationCtxt<'_, 'tcx>,
32+
key: ParamEnvAnd<'tcx, Self>,
33+
_span: Span,
34+
) -> Result<Self::QueryResponse, NoSolution> {
35+
Ok(key.value.value)
36+
}
37+
}
38+
39+
impl<'tcx, T> super::QueryTypeOp<'tcx> for DeeplyNormalize<T>
40+
where
41+
T: Normalizable<'tcx> + 'tcx,
42+
{
43+
type QueryResponse = T;
44+
45+
fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
46+
if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
47+
}
48+
49+
fn perform_query(
50+
tcx: TyCtxt<'tcx>,
51+
canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
52+
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
53+
T::type_op_method(
54+
tcx,
55+
CanonicalQueryInput {
56+
typing_mode: canonicalized.typing_mode,
57+
canonical: canonicalized.canonical.unchecked_map(
58+
|ty::ParamEnvAnd { param_env, value }| ty::ParamEnvAnd {
59+
param_env,
60+
value: Normalize { value: value.value },
61+
},
62+
),
63+
},
64+
)
65+
}
66+
3067
fn perform_locally_with_next_solver(
3168
ocx: &ObligationCtxt<'_, 'tcx>,
3269
key: ParamEnvAnd<'tcx, Self>,
3370
span: Span,
3471
) -> Result<Self::QueryResponse, NoSolution> {
35-
// FIXME(-Znext-solver): shouldn't be using old normalizer
36-
Ok(ocx.normalize(&ObligationCause::dummy_with_span(span), key.param_env, key.value.value))
72+
ocx.deeply_normalize(
73+
&ObligationCause::dummy_with_span(span),
74+
key.param_env,
75+
key.value.value,
76+
)
77+
.map_err(|_| NoSolution)
3778
}
3879
}
3980

@@ -81,3 +122,14 @@ impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
81122
tcx.type_op_normalize_fn_sig(canonicalized)
82123
}
83124
}
125+
126+
/// This impl is not needed, since we never normalize type outlives predicates
127+
/// in the old solver, but is required by trait bounds to be happy.
128+
impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
129+
fn type_op_method(
130+
_tcx: TyCtxt<'tcx>,
131+
_canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
132+
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
133+
unreachable!("we never normalize PolyTypeOutlivesPredicate")
134+
}
135+
}

0 commit comments

Comments
 (0)