Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 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 |
Chris Wailes | 32f7835 | 2021-07-20 14:04:55 -0700 | [diff] [blame] | 6 | //! `rustc_traits`. |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 7 | |
Chris Wailes | 2f380c1 | 2022-11-09 13:04:22 -0800 | [diff] [blame] | 8 | use crate::error::DropCheckOverflow; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 9 | use crate::infer::canonical::{Canonical, QueryResponse}; |
| 10 | use crate::ty::error::TypeError; |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 11 | use crate::ty::subst::GenericArg; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 12 | use crate::ty::{self, Ty, TyCtxt}; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 13 | use rustc_span::source_map::Span; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 14 | |
| 15 | pub mod type_op { |
| 16 | use crate::ty::fold::TypeFoldable; |
Chris Wailes | 5c0824a | 2023-04-24 16:30:59 -0700 | [diff] [blame] | 17 | use crate::ty::{Predicate, Ty, TyCtxt, UserType}; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 18 | use std::fmt; |
| 19 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 20 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] |
| 21 | #[derive(TypeFoldable, TypeVisitable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 22 | pub struct AscribeUserType<'tcx> { |
| 23 | pub mir_ty: Ty<'tcx>, |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 24 | pub user_ty: UserType<'tcx>, |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | impl<'tcx> AscribeUserType<'tcx> { |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 28 | pub fn new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self { |
| 29 | Self { mir_ty, user_ty } |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 30 | } |
| 31 | } |
| 32 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 33 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] |
| 34 | #[derive(TypeFoldable, TypeVisitable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 35 | pub struct Eq<'tcx> { |
| 36 | pub a: Ty<'tcx>, |
| 37 | pub b: Ty<'tcx>, |
| 38 | } |
| 39 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 40 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] |
| 41 | #[derive(TypeFoldable, TypeVisitable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 42 | pub struct Subtype<'tcx> { |
| 43 | pub sub: Ty<'tcx>, |
| 44 | pub sup: Ty<'tcx>, |
| 45 | } |
| 46 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 47 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] |
| 48 | #[derive(TypeFoldable, TypeVisitable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 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 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 59 | #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] |
| 60 | #[derive(TypeFoldable, TypeVisitable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 61 | pub struct Normalize<T> { |
| 62 | pub value: T, |
| 63 | } |
| 64 | |
| 65 | impl<'tcx, T> Normalize<T> |
| 66 | where |
Chris Wailes | 5c0824a | 2023-04-24 16:30:59 -0700 | [diff] [blame] | 67 | T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>, |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 68 | { |
| 69 | pub fn new(value: T) -> Self { |
| 70 | Self { value } |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 75 | pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>; |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 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 | |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 95 | #[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 96 | pub struct NoSolution; |
| 97 | |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 98 | impl<'tcx> From<TypeError<'tcx>> for NoSolution { |
| 99 | fn from(_: TypeError<'tcx>) -> NoSolution { |
| 100 | NoSolution |
| 101 | } |
| 102 | } |
| 103 | |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 104 | #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 105 | pub struct DropckOutlivesResult<'tcx> { |
| 106 | pub kinds: Vec<GenericArg<'tcx>>, |
| 107 | pub overflows: Vec<Ty<'tcx>>, |
| 108 | } |
| 109 | |
| 110 | impl<'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 Wailes | 2f380c1 | 2022-11-09 13:04:22 -0800 | [diff] [blame] | 113 | tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty }); |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 114 | } |
| 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)] |
Charisee | 341341c | 2022-05-20 05:14:50 +0000 | [diff] [blame] | 132 | pub struct DropckConstraint<'tcx> { |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 133 | /// 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 | |
Charisee | 341341c | 2022-05-20 05:14:50 +0000 | [diff] [blame] | 146 | impl<'tcx> DropckConstraint<'tcx> { |
| 147 | pub fn empty() -> DropckConstraint<'tcx> { |
| 148 | DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 149 | } |
| 150 | } |
| 151 | |
Charisee | 341341c | 2022-05-20 05:14:50 +0000 | [diff] [blame] | 152 | impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> { |
| 153 | fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self { |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 154 | let mut result = Self::empty(); |
| 155 | |
Charisee | 341341c | 2022-05-20 05:14:50 +0000 | [diff] [blame] | 156 | for DropckConstraint { outlives, dtorck_types, overflows } in iter { |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 157 | 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)] |
| 167 | pub 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 Wailes | 2805eef | 2022-04-07 11:22:56 -0700 | [diff] [blame] | 179 | #[derive(Copy, Clone, Debug, HashStable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 180 | pub struct MethodAutoderefStepsResult<'tcx> { |
| 181 | /// The valid autoderef steps that could be find. |
Chris Wailes | 2805eef | 2022-04-07 11:22:56 -0700 | [diff] [blame] | 182 | pub steps: &'tcx [CandidateStep<'tcx>], |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 183 | /// If Some(T), a type autoderef reported an error on. |
Chris Wailes | 2805eef | 2022-04-07 11:22:56 -0700 | [diff] [blame] | 184 | pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 185 | /// 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)] |
| 191 | pub 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. |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 197 | #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 198 | pub 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. |
Charisee | b1d3280 | 2022-09-22 15:38:41 +0000 | [diff] [blame] | 210 | #[derive(Clone, Debug, TypeFoldable, TypeVisitable, Lift, HashStable)] |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 211 | pub enum OutlivesBound<'tcx> { |
| 212 | RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), |
| 213 | RegionSubParam(ty::Region<'tcx>, ty::ParamTy), |
Charisee | d720b3f | 2023-03-09 17:35:07 +0000 | [diff] [blame] | 214 | RegionSubAlias(ty::Region<'tcx>, ty::AliasTy<'tcx>), |
Thiébaud Weksteen | 3b664ca | 2020-11-26 14:41:59 +0100 | [diff] [blame] | 215 | } |