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 ocx.deeply_normalize(
37 &ObligationCause::dummy_with_span(span),
38 key.param_env,
39 Unnormalized::new_wip(key.value.value),
40 )
41 .map_err(|_| NoSolution)
42 }
43}
44
45impl<'tcx, T> super::QueryTypeOp<'tcx> for DeeplyNormalize<T>
46where
47 T: Normalizable<'tcx> + 'tcx,
48{
49 type QueryResponse = T;
50
51 fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
52 if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
53 }
54
55 fn perform_query(
56 tcx: TyCtxt<'tcx>,
57 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
58 ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
59 T::type_op_method(
60 tcx,
61 CanonicalQueryInput {
62 typing_mode: canonicalized.typing_mode,
63 canonical: canonicalized.canonical.unchecked_map(
64 |ty::ParamEnvAnd { param_env, value }| ty::ParamEnvAnd {
65 param_env,
66 value: Normalize { value: value.value },
67 },
68 ),
69 },
70 )
71 }
72
73 fn perform_locally_with_next_solver(
74 ocx: &ObligationCtxt<'_, 'tcx>,
75 key: ParamEnvAnd<'tcx, Self>,
76 span: Span,
77 ) -> Result<Self::QueryResponse, NoSolution> {
78 ocx.deeply_normalize(
79 &ObligationCause::dummy_with_span(span),
80 key.param_env,
81 Unnormalized::new_wip(key.value.value),
82 )
83 .map_err(|_| NoSolution)
84 }
85}
86
87pub trait Normalizable<'tcx>:
88 fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
89{
90 fn type_op_method(
91 tcx: TyCtxt<'tcx>,
92 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
93 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>;
94}
95
96impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
97 fn type_op_method(
98 tcx: TyCtxt<'tcx>,
99 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
100 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
101 tcx.type_op_normalize_ty(canonicalized)
102 }
103}
104
105impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> {
106 fn type_op_method(
107 tcx: TyCtxt<'tcx>,
108 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
109 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
110 tcx.type_op_normalize_clause(canonicalized)
111 }
112}
113
114impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
115 fn type_op_method(
116 tcx: TyCtxt<'tcx>,
117 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
118 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
119 tcx.type_op_normalize_poly_fn_sig(canonicalized)
120 }
121}
122
123impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
124 fn type_op_method(
125 tcx: TyCtxt<'tcx>,
126 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
127 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
128 tcx.type_op_normalize_fn_sig(canonicalized)
129 }
130}
131
132impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
135 fn type_op_method(
136 _tcx: TyCtxt<'tcx>,
137 _canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
138 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
139 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("we never normalize PolyTypeOutlivesPredicate")));
}unreachable!("we never normalize PolyTypeOutlivesPredicate")
140 }
141}