]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/query/type_op/normalize.rs
Remove unnecessary lift calls
[rust.git] / src / librustc / traits / query / type_op / normalize.rs
1 use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
2 use std::fmt;
3 use crate::traits::query::Fallible;
4 use crate::ty::fold::TypeFoldable;
5 use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt};
6
7 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
8 pub struct Normalize<T> {
9     pub value: T,
10 }
11
12 impl<'tcx, T> Normalize<T>
13 where
14     T: fmt::Debug + TypeFoldable<'tcx>,
15 {
16     pub fn new(value: T) -> Self {
17         Self { value }
18     }
19 }
20
21 impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<T>
22 where
23     T: Normalizable<'tcx> + 'tcx,
24 {
25     type QueryResponse = T;
26
27     fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
28         if !key.value.value.has_projections() {
29             Some(key.value.value)
30         } else {
31             None
32         }
33     }
34
35     fn perform_query(
36         tcx: TyCtxt<'tcx>,
37         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
38     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self::QueryResponse>> {
39         T::type_op_method(tcx, canonicalized)
40     }
41
42     fn shrink_to_tcx_lifetime(
43         v: &'a CanonicalizedQueryResponse<'tcx, T>,
44     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, T>> {
45         T::shrink_to_tcx_lifetime(v)
46     }
47 }
48
49 pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy {
50     fn type_op_method(
51         tcx: TyCtxt<'tcx>,
52         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
53     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>>;
54
55     /// Converts from the `'tcx` (lifted) form of `Self` into the `tcx`
56     /// form of `Self`.
57     fn shrink_to_tcx_lifetime(
58         v: &'a CanonicalizedQueryResponse<'tcx, Self>,
59     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>>;
60 }
61
62 impl Normalizable<'tcx> for Ty<'tcx> {
63     fn type_op_method(
64         tcx: TyCtxt<'tcx>,
65         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
66     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
67         tcx.type_op_normalize_ty(canonicalized)
68     }
69
70     fn shrink_to_tcx_lifetime(
71         v: &'a CanonicalizedQueryResponse<'tcx, Self>,
72     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
73         v
74     }
75 }
76
77 impl Normalizable<'tcx> for ty::Predicate<'tcx> {
78     fn type_op_method(
79         tcx: TyCtxt<'tcx>,
80         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
81     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
82         tcx.type_op_normalize_predicate(canonicalized)
83     }
84
85     fn shrink_to_tcx_lifetime(
86         v: &'a CanonicalizedQueryResponse<'tcx, Self>,
87     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
88         v
89     }
90 }
91
92 impl Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
93     fn type_op_method(
94         tcx: TyCtxt<'tcx>,
95         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
96     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
97         tcx.type_op_normalize_poly_fn_sig(canonicalized)
98     }
99
100     fn shrink_to_tcx_lifetime(
101         v: &'a CanonicalizedQueryResponse<'tcx, Self>,
102     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
103         v
104     }
105 }
106
107 impl Normalizable<'tcx> for ty::FnSig<'tcx> {
108     fn type_op_method(
109         tcx: TyCtxt<'tcx>,
110         canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
111     ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
112         tcx.type_op_normalize_fn_sig(canonicalized)
113     }
114
115     fn shrink_to_tcx_lifetime(
116         v: &'a CanonicalizedQueryResponse<'tcx, Self>,
117     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
118         v
119     }
120 }
121
122 BraceStructTypeFoldableImpl! {
123     impl<'tcx, T> TypeFoldable<'tcx> for Normalize<T> {
124         value,
125     } where T: TypeFoldable<'tcx>,
126 }
127
128 BraceStructLiftImpl! {
129     impl<'tcx, T> Lift<'tcx> for Normalize<T> {
130         type Lifted = Normalize<T::Lifted>;
131         value,
132     } where T: Lift<'tcx>,
133 }
134
135 impl_stable_hash_for! {
136     impl<T> for struct Normalize<T> {
137         value
138     }
139 }