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
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
;
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
;
24 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
25 #[derive(TypeFoldable, TypeVisitable)]
26 pub struct AscribeUserType
<'tcx
> {
29 pub user_substs
: UserSubsts
<'tcx
>,
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 }
38 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
39 #[derive(TypeFoldable, TypeVisitable)]
45 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
46 #[derive(TypeFoldable, TypeVisitable)]
47 pub struct Subtype
<'tcx
> {
52 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
53 #[derive(TypeFoldable, TypeVisitable)]
54 pub struct ProvePredicate
<'tcx
> {
55 pub predicate
: Predicate
<'tcx
>,
58 impl<'tcx
> ProvePredicate
<'tcx
> {
59 pub fn new(predicate
: Predicate
<'tcx
>) -> Self {
60 ProvePredicate { predicate }
64 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
65 #[derive(TypeFoldable, TypeVisitable)]
66 pub struct Normalize
<T
> {
70 impl<'tcx
, T
> Normalize
<T
>
72 T
: fmt
::Debug
+ TypeFoldable
<'tcx
>,
74 pub fn new(value
: T
) -> Self {
80 pub type CanonicalProjectionGoal
<'tcx
> =
81 Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, ty
::ProjectionTy
<'tcx
>>>;
83 pub type CanonicalTyGoal
<'tcx
> = Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, Ty
<'tcx
>>>;
85 pub type CanonicalPredicateGoal
<'tcx
> = Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, ty
::Predicate
<'tcx
>>>;
87 pub type CanonicalTypeOpAscribeUserTypeGoal
<'tcx
> =
88 Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, type_op
::AscribeUserType
<'tcx
>>>;
90 pub type CanonicalTypeOpEqGoal
<'tcx
> = Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, type_op
::Eq
<'tcx
>>>;
92 pub type CanonicalTypeOpSubtypeGoal
<'tcx
> =
93 Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, type_op
::Subtype
<'tcx
>>>;
95 pub type CanonicalTypeOpProvePredicateGoal
<'tcx
> =
96 Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, type_op
::ProvePredicate
<'tcx
>>>;
98 pub type CanonicalTypeOpNormalizeGoal
<'tcx
, T
> =
99 Canonical
<'tcx
, ty
::ParamEnvAnd
<'tcx
, type_op
::Normalize
<T
>>>;
101 #[derive(Copy, Clone, Debug, HashStable)]
102 pub struct NoSolution
;
104 pub type Fallible
<T
> = Result
<T
, NoSolution
>;
106 impl<'tcx
> From
<TypeError
<'tcx
>> for NoSolution
{
107 fn from(_
: TypeError
<'tcx
>) -> NoSolution
{
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
>>,
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 }
);
125 pub fn into_kinds_reporting_overflows(
130 ) -> Vec
<GenericArg
<'tcx
>> {
131 self.report_overflows(tcx
, span
, ty
);
132 let DropckOutlivesResult { kinds, overflows: _ }
= self;
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
>>,
145 /// Types that could not be resolved: projections and params.
146 pub dtorck_types
: Vec
<Ty
<'tcx
>>,
148 /// If, during the computation of the dtorck constraint, we
149 /// overflow, that gets recorded here. The caller is expected to
151 pub overflows
: Vec
<Ty
<'tcx
>>,
154 impl<'tcx
> DropckConstraint
<'tcx
> {
155 pub fn empty() -> DropckConstraint
<'tcx
> {
156 DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
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();
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
);
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
,
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
195 pub reached_recursion_limit
: bool
,
198 #[derive(Debug, HashStable)]
199 pub struct MethodAutoderefBadTy
<'tcx
> {
200 pub reached_raw_pointer
: bool
,
201 pub ty
: Canonical
<'tcx
, QueryResponse
<'tcx
, Ty
<'tcx
>>>,
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
>,
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
>),