rustc_trait_selection/traits/query/type_op/
normalize.rs1use std::fmt;
2
3use rustc_middle::traits::ObligationCause;
4use rustc_middle::traits::query::NoSolution;
5pub use rustc_middle::traits::query::type_op::{DeeplyNormalize, Normalize};
6use rustc_middle::ty::{
7 self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Unnormalized,
8};
9use rustc_span::Span;
10
11use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
12use crate::traits::ObligationCtxt;
13
14impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<T>
15where
16 T: Normalizable<'tcx> + 'tcx,
17{
18 type QueryResponse = T;
19
20 fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
21 if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
22 }
23
24 fn perform_query(
25 tcx: TyCtxt<'tcx>,
26 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
27 ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
28 T::type_op_method(tcx, canonicalized)
29 }
30
31 fn perform_locally_with_next_solver(
32 _ocx: &ObligationCtxt<'_, 'tcx>,
33 key: ParamEnvAnd<'tcx, Self>,
34 _span: Span,
35 ) -> Result<Self::QueryResponse, NoSolution> {
36 Ok(key.value.value)
37 }
38}
39
40impl<'tcx, T> super::QueryTypeOp<'tcx> for DeeplyNormalize<T>
41where
42 T: Normalizable<'tcx> + 'tcx,
43{
44 type QueryResponse = T;
45
46 fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
47 if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
48 }
49
50 fn perform_query(
51 tcx: TyCtxt<'tcx>,
52 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
53 ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
54 T::type_op_method(
55 tcx,
56 CanonicalQueryInput {
57 typing_mode: canonicalized.typing_mode,
58 canonical: canonicalized.canonical.unchecked_map(
59 |ty::ParamEnvAnd { param_env, value }| ty::ParamEnvAnd {
60 param_env,
61 value: Normalize { value: value.value },
62 },
63 ),
64 },
65 )
66 }
67
68 fn perform_locally_with_next_solver(
69 ocx: &ObligationCtxt<'_, 'tcx>,
70 key: ParamEnvAnd<'tcx, Self>,
71 span: Span,
72 ) -> Result<Self::QueryResponse, NoSolution> {
73 ocx.deeply_normalize(
74 &ObligationCause::dummy_with_span(span),
75 key.param_env,
76 Unnormalized::new_wip(key.value.value),
77 )
78 .map_err(|_| NoSolution)
79 }
80}
81
82pub trait Normalizable<'tcx>:
83 fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
84{
85 fn type_op_method(
86 tcx: TyCtxt<'tcx>,
87 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
88 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>;
89}
90
91impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
92 fn type_op_method(
93 tcx: TyCtxt<'tcx>,
94 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
95 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
96 tcx.type_op_normalize_ty(canonicalized)
97 }
98}
99
100impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> {
101 fn type_op_method(
102 tcx: TyCtxt<'tcx>,
103 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
104 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
105 tcx.type_op_normalize_clause(canonicalized)
106 }
107}
108
109impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
110 fn type_op_method(
111 tcx: TyCtxt<'tcx>,
112 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
113 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
114 tcx.type_op_normalize_poly_fn_sig(canonicalized)
115 }
116}
117
118impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
119 fn type_op_method(
120 tcx: TyCtxt<'tcx>,
121 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
122 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
123 tcx.type_op_normalize_fn_sig(canonicalized)
124 }
125}
126
127impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
130 fn type_op_method(
131 _tcx: TyCtxt<'tcx>,
132 _canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
133 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
134 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("we never normalize PolyTypeOutlivesPredicate")));
}unreachable!("we never normalize PolyTypeOutlivesPredicate")
135 }
136}