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