• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
12 use crate::ty::{self, Ty, TyCtxt};
13 use rustc_span::source_map::Span;
14 
15 pub mod type_op {
16     use crate::ty::fold::TypeFoldable;
17     use crate::ty::{Predicate, Ty, TyCtxt, UserType};
18     use std::fmt;
19 
20     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
21     #[derive(TypeFoldable, TypeVisitable)]
22     pub struct AscribeUserType<'tcx> {
23         pub mir_ty: Ty<'tcx>,
24         pub user_ty: UserType<'tcx>,
25     }
26 
27     impl<'tcx> AscribeUserType<'tcx> {
new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self28         pub fn new(mir_ty: Ty<'tcx>, user_ty: UserType<'tcx>) -> Self {
29             Self { mir_ty, user_ty }
30         }
31     }
32 
33     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
34     #[derive(TypeFoldable, TypeVisitable)]
35     pub struct Eq<'tcx> {
36         pub a: Ty<'tcx>,
37         pub b: Ty<'tcx>,
38     }
39 
40     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
41     #[derive(TypeFoldable, TypeVisitable)]
42     pub struct Subtype<'tcx> {
43         pub sub: Ty<'tcx>,
44         pub sup: Ty<'tcx>,
45     }
46 
47     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
48     #[derive(TypeFoldable, TypeVisitable)]
49     pub struct ProvePredicate<'tcx> {
50         pub predicate: Predicate<'tcx>,
51     }
52 
53     impl<'tcx> ProvePredicate<'tcx> {
new(predicate: Predicate<'tcx>) -> Self54         pub fn new(predicate: Predicate<'tcx>) -> Self {
55             ProvePredicate { predicate }
56         }
57     }
58 
59     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
60     #[derive(TypeFoldable, TypeVisitable)]
61     pub struct Normalize<T> {
62         pub value: T,
63     }
64 
65     impl<'tcx, T> Normalize<T>
66     where
67         T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
68     {
new(value: T) -> Self69         pub fn new(value: T) -> Self {
70             Self { value }
71         }
72     }
73 }
74 
75 pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
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 
95 #[derive(Copy, Clone, Debug, Hash, HashStable, PartialEq, Eq)]
96 pub struct NoSolution;
97 
98 impl<'tcx> From<TypeError<'tcx>> for NoSolution {
from(_: TypeError<'tcx>) -> NoSolution99     fn from(_: TypeError<'tcx>) -> NoSolution {
100         NoSolution
101     }
102 }
103 
104 #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)]
105 pub struct DropckOutlivesResult<'tcx> {
106     pub kinds: Vec<GenericArg<'tcx>>,
107     pub overflows: Vec<Ty<'tcx>>,
108 }
109 
110 impl<'tcx> DropckOutlivesResult<'tcx> {
report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'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) {
113             tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty });
114         }
115     }
116 
into_kinds_reporting_overflows( self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>, ) -> Vec<GenericArg<'tcx>>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)]
132 pub struct DropckConstraint<'tcx> {
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 
146 impl<'tcx> DropckConstraint<'tcx> {
empty() -> DropckConstraint<'tcx>147     pub fn empty() -> DropckConstraint<'tcx> {
148         DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
149     }
150 }
151 
152 impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> {
from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self153     fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self {
154         let mut result = Self::empty();
155 
156         for DropckConstraint { outlives, dtorck_types, overflows } in iter {
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 
179 #[derive(Copy, Clone, Debug, HashStable)]
180 pub struct MethodAutoderefStepsResult<'tcx> {
181     /// The valid autoderef steps that could be find.
182     pub steps: &'tcx [CandidateStep<'tcx>],
183     /// If Some(T), a type autoderef reported an error on.
184     pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
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.
197 #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
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.
210 #[derive(Clone, Debug, TypeFoldable, TypeVisitable, Lift, HashStable)]
211 pub enum OutlivesBound<'tcx> {
212     RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
213     RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
214     RegionSubAlias(ty::Region<'tcx>, ty::AliasTy<'tcx>),
215 }
216