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::Normalize;
6use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
7use rustc_span::Span;
8
9use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
10use crate::traits::ObligationCtxt;
11
12impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<'tcx, T>
13where
14 T: Normalizable<'tcx> + 'tcx,
15{
16 type QueryResponse = T;
17
18 fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
19 if !key.value.value.skip_normalization().has_aliases() {
20 Some(key.value.value.skip_normalization())
21 } else {
22 None
23 }
24 }
25
26 fn perform_query(
27 tcx: TyCtxt<'tcx>,
28 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
29 ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
30 T::type_op_method(tcx, canonicalized)
31 }
32
33 fn perform_locally_with_next_solver(
34 ocx: &ObligationCtxt<'_, 'tcx>,
35 key: ParamEnvAnd<'tcx, Self>,
36 span: Span,
37 ) -> Result<Self::QueryResponse, NoSolution> {
38 ocx.deeply_normalize(
39 &ObligationCause::dummy_with_span(span),
40 key.param_env,
41 key.value.value,
42 )
43 .map_err(|_| NoSolution)
44 }
45}
46
47pub trait Normalizable<'tcx>:
48 fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
49{
50 fn type_op_method(
51 tcx: TyCtxt<'tcx>,
52 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
53 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution>;
54}
55
56impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
57 fn type_op_method(
58 tcx: TyCtxt<'tcx>,
59 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
60 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
61 tcx.type_op_normalize_ty(canonicalized)
62 }
63}
64
65impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> {
66 fn type_op_method(
67 tcx: TyCtxt<'tcx>,
68 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
69 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
70 tcx.type_op_normalize_clause(canonicalized)
71 }
72}
73
74impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
75 fn type_op_method(
76 tcx: TyCtxt<'tcx>,
77 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
78 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
79 tcx.type_op_normalize_poly_fn_sig(canonicalized)
80 }
81}
82
83impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> {
84 fn type_op_method(
85 tcx: TyCtxt<'tcx>,
86 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
87 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
88 tcx.type_op_normalize_fn_sig(canonicalized)
89 }
90}
91
92impl<'tcx> Normalizable<'tcx> for ty::PolyTypeOutlivesPredicate<'tcx> {
95 fn type_op_method(
96 _tcx: TyCtxt<'tcx>,
97 _canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Normalize<'tcx, Self>>>,
98 ) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
99 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("we never normalize PolyTypeOutlivesPredicate")));
}unreachable!("we never normalize PolyTypeOutlivesPredicate")
100 }
101}