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