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::infer::canonical::{Canonical, QueryResponse};
9 use crate::ty::error::TypeError;
10 use crate::ty::subst::GenericArg;
11 use crate::ty::{self, Ty, TyCtxt};
12 use rustc_errors::struct_span_err;
13 use rustc_span::source_map::Span;
14 use std::iter::FromIterator;
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;
23 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
24 #[derive(TypeFoldable, TypeVisitable)]
25 pub struct AscribeUserType<'tcx> {
28 pub user_substs: UserSubsts<'tcx>,
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 }
37 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
38 #[derive(TypeFoldable, TypeVisitable)]
44 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
45 #[derive(TypeFoldable, TypeVisitable)]
46 pub struct Subtype<'tcx> {
51 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
52 #[derive(TypeFoldable, TypeVisitable)]
53 pub struct ProvePredicate<'tcx> {
54 pub predicate: Predicate<'tcx>,
57 impl<'tcx> ProvePredicate<'tcx> {
58 pub fn new(predicate: Predicate<'tcx>) -> Self {
59 ProvePredicate { predicate }
63 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)]
64 #[derive(TypeFoldable, TypeVisitable)]
65 pub struct Normalize<T> {
69 impl<'tcx, T> Normalize<T>
71 T: fmt::Debug + TypeFoldable<'tcx>,
73 pub fn new(value: T) -> Self {
79 pub type CanonicalProjectionGoal<'tcx> =
80 Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>;
82 pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
84 pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
86 pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
87 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>;
89 pub type CanonicalTypeOpEqGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>;
91 pub type CanonicalTypeOpSubtypeGoal<'tcx> =
92 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>;
94 pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
95 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>;
97 pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
98 Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
100 #[derive(Copy, Clone, Debug, HashStable)]
101 pub struct NoSolution;
103 pub type Fallible<T> = Result<T, NoSolution>;
105 impl<'tcx> From<TypeError<'tcx>> for NoSolution {
106 fn from(_: TypeError<'tcx>) -> NoSolution {
111 #[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)]
112 pub struct DropckOutlivesResult<'tcx> {
113 pub kinds: Vec<GenericArg<'tcx>>,
114 pub overflows: Vec<Ty<'tcx>>,
117 impl<'tcx> DropckOutlivesResult<'tcx> {
118 pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
119 if let Some(overflow_ty) = self.overflows.get(0) {
120 let mut err = struct_span_err!(
124 "overflow while adding drop-check rules for {}",
127 err.note(&format!("overflowed on {}", overflow_ty));
132 pub fn into_kinds_reporting_overflows(
137 ) -> Vec<GenericArg<'tcx>> {
138 self.report_overflows(tcx, span, ty);
139 let DropckOutlivesResult { kinds, overflows: _ } = self;
144 /// A set of constraints that need to be satisfied in order for
145 /// a type to be valid for destruction.
146 #[derive(Clone, Debug, HashStable)]
147 pub struct DropckConstraint<'tcx> {
148 /// Types that are required to be alive in order for this
149 /// type to be valid for destruction.
150 pub outlives: Vec<ty::subst::GenericArg<'tcx>>,
152 /// Types that could not be resolved: projections and params.
153 pub dtorck_types: Vec<Ty<'tcx>>,
155 /// If, during the computation of the dtorck constraint, we
156 /// overflow, that gets recorded here. The caller is expected to
158 pub overflows: Vec<Ty<'tcx>>,
161 impl<'tcx> DropckConstraint<'tcx> {
162 pub fn empty() -> DropckConstraint<'tcx> {
163 DropckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] }
167 impl<'tcx> FromIterator<DropckConstraint<'tcx>> for DropckConstraint<'tcx> {
168 fn from_iter<I: IntoIterator<Item = DropckConstraint<'tcx>>>(iter: I) -> Self {
169 let mut result = Self::empty();
171 for DropckConstraint { outlives, dtorck_types, overflows } in iter {
172 result.outlives.extend(outlives);
173 result.dtorck_types.extend(dtorck_types);
174 result.overflows.extend(overflows);
181 #[derive(Debug, HashStable)]
182 pub struct CandidateStep<'tcx> {
183 pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
184 pub autoderefs: usize,
185 /// `true` if the type results from a dereference of a raw pointer.
186 /// when assembling candidates, we include these steps, but not when
187 /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
188 /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
189 /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
190 pub from_unsafe_deref: bool,
194 #[derive(Copy, Clone, Debug, HashStable)]
195 pub struct MethodAutoderefStepsResult<'tcx> {
196 /// The valid autoderef steps that could be find.
197 pub steps: &'tcx [CandidateStep<'tcx>],
198 /// If Some(T), a type autoderef reported an error on.
199 pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
200 /// If `true`, `steps` has been truncated due to reaching the
202 pub reached_recursion_limit: bool,
205 #[derive(Debug, HashStable)]
206 pub struct MethodAutoderefBadTy<'tcx> {
207 pub reached_raw_pointer: bool,
208 pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
211 /// Result from the `normalize_projection_ty` query.
212 #[derive(Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)]
213 pub struct NormalizationResult<'tcx> {
214 /// Result of normalization.
215 pub normalized_ty: Ty<'tcx>,
218 /// Outlives bounds are relationships between generic parameters,
219 /// whether they both be regions (`'a: 'b`) or whether types are
220 /// involved (`T: 'a`). These relationships can be extracted from the
221 /// full set of predicates we understand or also from types (in which
222 /// case they are called implied bounds). They are fed to the
223 /// `OutlivesEnv` which in turn is supplied to the region checker and
224 /// other parts of the inference system.
225 #[derive(Clone, Debug, TypeFoldable, TypeVisitable, Lift, HashStable)]
226 pub enum OutlivesBound<'tcx> {
227 RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
228 RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
229 RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),