]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/traits/query.rs
Merge commit '1480cea393d0cee195e59949eabdfbcf1230f7f9' into clippyup
[rust.git] / compiler / rustc_middle / src / traits / query.rs
1 //! Experimental types for the trait query interface. The methods
2 //! defined in this module are all based on **canonicalization**,
3 //! which makes a canonical query by replacing unbound inference
4 //! variables and regions, so that results can be reused more broadly.
5 //! The providers for the queries defined here can be found in
6 //! `rustc_traits`.
7
8 use crate::error::DropCheckOverflow;
9 use crate::infer::canonical::{Canonical, QueryResponse};
10 use crate::ty::error::TypeError;
11 use crate::ty::subst::GenericArg;
12 use crate::ty::{self, Ty, TyCtxt};
13 use rustc_span::source_map::Span;
14
15 pub mod type_op {
16     use crate::ty::fold::TypeFoldable;
17     use crate::ty::{Predicate, Ty, UserType};
18     use std::fmt;
19
20     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
21     #[derive(TypeFoldable, TypeVisitable)]
22     pub struct AscribeUserType<'tcx> {
23         pub mir_ty: Ty<'tcx>,
24         pub user_ty: UserType<'tcx>,
25     }
26
27     impl<'tcx> AscribeUserType<'tcx> {
28         pub fn new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self {
29             Self { mir_ty, user_ty }
30         }
31     }
32
33     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
34     #[derive(TypeFoldable, TypeVisitable)]
35     pub struct Eq<'tcx> {
36         pub a: Ty<'tcx>,
37         pub b: Ty<'tcx>,
38     }
39
40     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
41     #[derive(TypeFoldable, TypeVisitable)]
42     pub struct Subtype<'tcx> {
43         pub sub: Ty<'tcx>,
44         pub sup: Ty<'tcx>,
45     }
46
47     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
48     #[derive(TypeFoldable, TypeVisitable)]
49     pub struct ProvePredicate<'tcx> {
50         pub predicate: Predicate<'tcx>,
51     }
52
53     impl<'tcx> ProvePredicate<'tcx> {
54         pub fn new(predicate: Predicate<'tcx>) -> Self {
55             ProvePredicate { predicate }
56         }
57     }
58
59     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
60     #[derive(TypeFoldable, TypeVisitable)]
61     pub struct Normalize<T> {
62         pub value: T,
63     }
64
65     impl<'tcx, T> Normalize<T>
66     where
67         T: fmt::Debug + TypeFoldable<'tcx>,
68     {
69         pub fn new(value: T) -> Self {
70             Self { value }
71         }
72     }
73 }
74
75 pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
76
77 pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
78
79 pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
80
81 pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
82     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>;
83
84 pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>;
85
86 pub type CanonicalTypeOpSubtypeGoal<'tcx> =
87     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>;
88
89 pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
90     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>;
91
92 pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
93     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
94
95 #[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)]
96 pub struct NoSolution;
97
98 pub type Fallible<T> = Result<T, NoSolution>;
99
100 impl<'tcx> From<TypeError<'tcx>> for NoSolution {
101     fn from(_: TypeError<'tcx>) -> NoSolution {
102         NoSolution
103     }
104 }
105
106 #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)]
107 pub struct DropckOutlivesResult<'tcx> {
108     pub kinds: Vec<GenericArg<'tcx>>,
109     pub overflows: Vec<Ty<'tcx>>,
110 }
111
112 impl<'tcx> DropckOutlivesResult<'tcx> {
113     pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
114         if let Some(overflow_ty) = self.overflows.get(0) {
115             tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty });
116         }
117     }
118
119     pub fn into_kinds_reporting_overflows(
120         self,
121         tcx: TyCtxt<'tcx>,
122         span: Span,
123         ty: Ty<'tcx>,
124     ) -> Vec<GenericArg<'tcx>> {
125         self.report_overflows(tcx, span, ty);
126         let DropckOutlivesResult { kinds, overflows: _ } = self;
127         kinds
128     }
129 }
130
131 /// A set of constraints that need to be satisfied in order for
132 /// a type to be valid for destruction.
133 #[derive(Clone, Debug, HashStable)]
134 pub struct DropckConstraint<'tcx> {
135     /// Types that are required to be alive in order for this
136     /// type to be valid for destruction.
137     pub outlives: Vec<ty::subst::GenericArg<'tcx>>,
138
139     /// Types that could not be resolved: projections and params.
140     pub dtorck_types: Vec<Ty<'tcx>>,
141
142     /// If, during the computation of the dtorck constraint, we
143     /// overflow, that gets recorded here. The caller is expected to
144     /// report an error.
145     pub overflows: Vec<Ty<'tcx>>,
146 }
147
148 impl<'tcx> DropckConstraint<'tcx> {
149     pub fn empty() -> DropckConstraint<'tcx> {
150         DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
151     }
152 }
153
154 impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> {
155     fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self {
156         let mut result = Self::empty();
157
158         for DropckConstraint { outlives, dtorck_types, overflows } in iter {
159             result.outlives.extend(outlives);
160             result.dtorck_types.extend(dtorck_types);
161             result.overflows.extend(overflows);
162         }
163
164         result
165     }
166 }
167
168 #[derive(Debug, HashStable)]
169 pub struct CandidateStep<'tcx> {
170     pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
171     pub autoderefs: usize,
172     /// `true` if the type results from a dereference of a raw pointer.
173     /// when assembling candidates, we include these steps, but not when
174     /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
175     /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
176     /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
177     pub from_unsafe_deref: bool,
178     pub unsize: bool,
179 }
180
181 #[derive(Copy, Clone, Debug, HashStable)]
182 pub struct MethodAutoderefStepsResult<'tcx> {
183     /// The valid autoderef steps that could be find.
184     pub steps: &'tcx [CandidateStep<'tcx>],
185     /// If Some(T), a type autoderef reported an error on.
186     pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
187     /// If `true`, `steps` has been truncated due to reaching the
188     /// recursion limit.
189     pub reached_recursion_limit: bool,
190 }
191
192 #[derive(Debug, HashStable)]
193 pub struct MethodAutoderefBadTy<'tcx> {
194     pub reached_raw_pointer: bool,
195     pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
196 }
197
198 /// Result from the `normalize_projection_ty` query.
199 #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
200 pub struct NormalizationResult<'tcx> {
201     /// Result of normalization.
202     pub normalized_ty: Ty<'tcx>,
203 }
204
205 /// Outlives bounds are relationships between generic parameters,
206 /// whether they both be regions (`'a: 'b`) or whether types are
207 /// involved (`T: 'a`). These relationships can be extracted from the
208 /// full set of predicates we understand or also from types (in which
209 /// case they are called implied bounds). They are fed to the
210 /// `OutlivesEnv` which in turn is supplied to the region checker and
211 /// other parts of the inference system.
212 #[derive(Clone, Debug, TypeFoldable, TypeVisitable, Lift, HashStable)]
213 pub enum OutlivesBound<'tcx> {
214     RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
215     RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
216     RegionSubAlias(ty::Region<'tcx>, ty::AliasTy<'tcx>),
217 }