blob: eae5a280e114d0a9aa953b6a7212a6ca58ffdbd0 [file] [log] [blame]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +01001//! 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
Chris Wailes32f78352021-07-20 14:04:55 -07006//! `rustc_traits`.
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +01007
Chris Wailes2f380c12022-11-09 13:04:22 -08008use crate::error::DropCheckOverflow;
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +01009use crate::infer::canonical::{Canonical, QueryResponse};
10use crate::ty::error::TypeError;
Chariseed720b3f2023-03-09 17:35:07 +000011use crate::ty::subst::GenericArg;
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010012use crate::ty::{self, Ty, TyCtxt};
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010013use rustc_span::source_map::Span;
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010014
15pub mod type_op {
16 use crate::ty::fold::TypeFoldable;
Chris Wailes5c0824a2023-04-24 16:30:59 -070017 use crate::ty::{Predicate, Ty, TyCtxt, UserType};
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010018 use std::fmt;
19
Chariseeb1d32802022-09-22 15:38:41 +000020 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
21 #[derive(TypeFoldable, TypeVisitable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010022 pub struct AscribeUserType<'tcx> {
23 pub mir_ty: Ty<'tcx>,
Chariseed720b3f2023-03-09 17:35:07 +000024 pub user_ty: UserType<'tcx>,
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010025 }
26
27 impl<'tcx> AscribeUserType<'tcx> {
Chariseed720b3f2023-03-09 17:35:07 +000028 pub fn new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self {
29 Self { mir_ty, user_ty }
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010030 }
31 }
32
Chariseeb1d32802022-09-22 15:38:41 +000033 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
34 #[derive(TypeFoldable, TypeVisitable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010035 pub struct Eq<'tcx> {
36 pub a: Ty<'tcx>,
37 pub b: Ty<'tcx>,
38 }
39
Chariseeb1d32802022-09-22 15:38:41 +000040 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
41 #[derive(TypeFoldable, TypeVisitable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010042 pub struct Subtype<'tcx> {
43 pub sub: Ty<'tcx>,
44 pub sup: Ty<'tcx>,
45 }
46
Chariseeb1d32802022-09-22 15:38:41 +000047 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
48 #[derive(TypeFoldable, TypeVisitable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010049 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
Chariseeb1d32802022-09-22 15:38:41 +000059 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
60 #[derive(TypeFoldable, TypeVisitable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010061 pub struct Normalize<T> {
62 pub value: T,
63 }
64
65 impl<'tcx, T> Normalize<T>
66 where
Chris Wailes5c0824a2023-04-24 16:30:59 -070067 T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010068 {
69 pub fn new(value: T) -> Self {
70 Self { value }
71 }
72 }
73}
74
Chariseed720b3f2023-03-09 17:35:07 +000075pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010076
77pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
78
79pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
80
81pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
82 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>;
83
84pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>;
85
86pub type CanonicalTypeOpSubtypeGoal<'tcx> =
87 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>;
88
89pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
90 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>;
91
92pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
93 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
94
Chariseed720b3f2023-03-09 17:35:07 +000095#[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010096pub struct NoSolution;
97
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +010098impl<'tcx> From<TypeError<'tcx>> for NoSolution {
99 fn from(_: TypeError<'tcx>) -> NoSolution {
100 NoSolution
101 }
102}
103
Chariseeb1d32802022-09-22 15:38:41 +0000104#[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100105pub struct DropckOutlivesResult<'tcx> {
106 pub kinds: Vec<GenericArg<'tcx>>,
107 pub overflows: Vec<Ty<'tcx>>,
108}
109
110impl<'tcx> DropckOutlivesResult<'tcx> {
111 pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
112 if let Some(overflow_ty) = self.overflows.get(0) {
Chris Wailes2f380c12022-11-09 13:04:22 -0800113 tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty });
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100114 }
115 }
116
117 pub fn into_kinds_reporting_overflows(
118 self,
119 tcx: TyCtxt<'tcx>,
120 span: Span,
121 ty: Ty<'tcx>,
122 ) -> Vec<GenericArg<'tcx>> {
123 self.report_overflows(tcx, span, ty);
124 let DropckOutlivesResult { kinds, overflows: _ } = self;
125 kinds
126 }
127}
128
129/// A set of constraints that need to be satisfied in order for
130/// a type to be valid for destruction.
131#[derive(Clone, Debug, HashStable)]
Charisee341341c2022-05-20 05:14:50 +0000132pub struct DropckConstraint<'tcx> {
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100133 /// Types that are required to be alive in order for this
134 /// type to be valid for destruction.
135 pub outlives: Vec<ty::subst::GenericArg<'tcx>>,
136
137 /// Types that could not be resolved: projections and params.
138 pub dtorck_types: Vec<Ty<'tcx>>,
139
140 /// If, during the computation of the dtorck constraint, we
141 /// overflow, that gets recorded here. The caller is expected to
142 /// report an error.
143 pub overflows: Vec<Ty<'tcx>>,
144}
145
Charisee341341c2022-05-20 05:14:50 +0000146impl<'tcx> DropckConstraint<'tcx> {
147 pub fn empty() -> DropckConstraint<'tcx> {
148 DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100149 }
150}
151
Charisee341341c2022-05-20 05:14:50 +0000152impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> {
153 fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self {
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100154 let mut result = Self::empty();
155
Charisee341341c2022-05-20 05:14:50 +0000156 for DropckConstraint { outlives, dtorck_types, overflows } in iter {
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100157 result.outlives.extend(outlives);
158 result.dtorck_types.extend(dtorck_types);
159 result.overflows.extend(overflows);
160 }
161
162 result
163 }
164}
165
166#[derive(Debug, HashStable)]
167pub struct CandidateStep<'tcx> {
168 pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
169 pub autoderefs: usize,
170 /// `true` if the type results from a dereference of a raw pointer.
171 /// when assembling candidates, we include these steps, but not when
172 /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
173 /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
174 /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
175 pub from_unsafe_deref: bool,
176 pub unsize: bool,
177}
178
Chris Wailes2805eef2022-04-07 11:22:56 -0700179#[derive(Copy, Clone, Debug, HashStable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100180pub struct MethodAutoderefStepsResult<'tcx> {
181 /// The valid autoderef steps that could be find.
Chris Wailes2805eef2022-04-07 11:22:56 -0700182 pub steps: &'tcx [CandidateStep<'tcx>],
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100183 /// If Some(T), a type autoderef reported an error on.
Chris Wailes2805eef2022-04-07 11:22:56 -0700184 pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100185 /// If `true`, `steps` has been truncated due to reaching the
186 /// recursion limit.
187 pub reached_recursion_limit: bool,
188}
189
190#[derive(Debug, HashStable)]
191pub struct MethodAutoderefBadTy<'tcx> {
192 pub reached_raw_pointer: bool,
193 pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
194}
195
196/// Result from the `normalize_projection_ty` query.
Chariseeb1d32802022-09-22 15:38:41 +0000197#[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100198pub struct NormalizationResult<'tcx> {
199 /// Result of normalization.
200 pub normalized_ty: Ty<'tcx>,
201}
202
203/// Outlives bounds are relationships between generic parameters,
204/// whether they both be regions (`'a: 'b`) or whether types are
205/// involved (`T: 'a`). These relationships can be extracted from the
206/// full set of predicates we understand or also from types (in which
207/// case they are called implied bounds). They are fed to the
208/// `OutlivesEnv` which in turn is supplied to the region checker and
209/// other parts of the inference system.
Chariseeb1d32802022-09-22 15:38:41 +0000210#[derive(Clone, Debug, TypeFoldable, TypeVisitable, Lift, HashStable)]
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100211pub enum OutlivesBound<'tcx> {
212 RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
213 RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
Chariseed720b3f2023-03-09 17:35:07 +0000214 RegionSubAlias(ty::Region<'tcx>, ty::AliasTy<'tcx>),
Thiébaud Weksteen3b664ca2020-11-26 14:41:59 +0100215}