1mod engine;
6mod project;
7mod structural_impls;
8pub mod util;
9
10use std::cmp;
11use std::hash::{Hash, Hasher};
12
13use hir::def_id::LocalDefId;
14use rustc_hir as hir;
15use rustc_macros::{TypeFoldable, TypeVisitable};
16use rustc_middle::traits::query::NoSolution;
17use rustc_middle::traits::solve::Certainty;
18pub use rustc_middle::traits::*;
19use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
20use rustc_span::Span;
21use thin_vec::ThinVec;
22
23pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine};
24pub(crate) use self::project::UndoLog;
25pub use self::project::{
26 MismatchedProjectionTypes, Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry,
27 ProjectionCacheKey, ProjectionCacheStorage,
28};
29use crate::infer::InferCtxt;
30
31#[derive(#[automatically_derived]
impl<'tcx, T: ::core::clone::Clone> ::core::clone::Clone for
Obligation<'tcx, T> {
#[inline]
fn clone(&self) -> Obligation<'tcx, T> {
Obligation {
cause: ::core::clone::Clone::clone(&self.cause),
param_env: ::core::clone::Clone::clone(&self.param_env),
predicate: ::core::clone::Clone::clone(&self.predicate),
recursion_depth: ::core::clone::Clone::clone(&self.recursion_depth),
}
}
}Clone, const _: () =
{
impl<'tcx, T>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for Obligation<'tcx, T> where
T: ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
{
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
Obligation {
cause: __binding_0,
param_env: __binding_1,
predicate: __binding_2,
recursion_depth: __binding_3 } => {
Obligation {
cause: __binding_0,
param_env: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
__folder)?,
predicate: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_2,
__folder)?,
recursion_depth: __binding_3,
}
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
Obligation {
cause: __binding_0,
param_env: __binding_1,
predicate: __binding_2,
recursion_depth: __binding_3 } => {
Obligation {
cause: __binding_0,
param_env: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
__folder),
predicate: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_2,
__folder),
recursion_depth: __binding_3,
}
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx, T>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for Obligation<'tcx, T> where
T: ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
{
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
Obligation {
param_env: ref __binding_1, predicate: ref __binding_2, .. }
=> {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_2,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
38pub struct Obligation<'tcx, T> {
39 #[type_foldable(identity)]
43 #[type_visitable(ignore)]
44 pub cause: ObligationCause<'tcx>,
45
46 pub param_env: ty::ParamEnv<'tcx>,
48
49 pub predicate: T,
51
52 #[type_foldable(identity)]
58 #[type_visitable(ignore)]
59 pub recursion_depth: usize,
60}
61
62impl<'tcx, T: Copy> Obligation<'tcx, T> {
63 pub fn as_goal(&self) -> solve::Goal<'tcx, T> {
64 solve::Goal { param_env: self.param_env, predicate: self.predicate }
65 }
66}
67
68impl<'tcx, T: PartialEq> PartialEq<Obligation<'tcx, T>> for Obligation<'tcx, T> {
69 #[inline]
70 fn eq(&self, other: &Obligation<'tcx, T>) -> bool {
71 self.param_env == other.param_env && self.predicate == other.predicate
76 }
77}
78
79impl<T: Eq> Eq for Obligation<'_, T> {}
80
81impl<T: Hash> Hash for Obligation<'_, T> {
82 fn hash<H: Hasher>(&self, state: &mut H) -> () {
83 self.param_env.hash(state);
85 self.predicate.hash(state);
86 }
87}
88
89pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
90pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>;
91pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
92
93pub type PredicateObligations<'tcx> = ThinVec<PredicateObligation<'tcx>>;
94
95impl<'tcx> PredicateObligation<'tcx> {
96 pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<PredicateObligation<'tcx>> {
100 Some(PredicateObligation {
101 cause: self.cause.clone(),
102 param_env: self.param_env,
103 predicate: self.predicate.flip_polarity(tcx)?,
104 recursion_depth: self.recursion_depth,
105 })
106 }
107}
108
109impl<'tcx> PolyTraitObligation<'tcx> {
110 pub fn derived_cause(
111 &self,
112 variant: impl FnOnce(DerivedCause<'tcx>) -> ObligationCauseCode<'tcx>,
113 ) -> ObligationCause<'tcx> {
114 self.cause.clone().derived_cause(self.predicate, variant)
115 }
116}
117
118#[cfg(target_pointer_width = "64")]
120const _: [(); 48] = [(); ::std::mem::size_of::<PredicateObligation<'_>>()];rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48);
121
122pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
123
124pub type ObligationInspector<'tcx> =
127 fn(&InferCtxt<'tcx>, &PredicateObligation<'tcx>, Result<Certainty, NoSolution>);
128
129impl<'tcx, O> Obligation<'tcx, O> {
130 pub fn new(
131 tcx: TyCtxt<'tcx>,
132 cause: ObligationCause<'tcx>,
133 param_env: ty::ParamEnv<'tcx>,
134 predicate: impl Upcast<TyCtxt<'tcx>, O>,
135 ) -> Obligation<'tcx, O> {
136 Self::with_depth(tcx, cause, 0, param_env, predicate)
137 }
138
139 pub fn set_depth_from_parent(&mut self, parent_depth: usize) {
144 self.recursion_depth = cmp::max(parent_depth + 1, self.recursion_depth);
145 }
146
147 pub fn with_depth(
148 tcx: TyCtxt<'tcx>,
149 cause: ObligationCause<'tcx>,
150 recursion_depth: usize,
151 param_env: ty::ParamEnv<'tcx>,
152 predicate: impl Upcast<TyCtxt<'tcx>, O>,
153 ) -> Obligation<'tcx, O> {
154 let predicate = predicate.upcast(tcx);
155 Obligation { cause, param_env, recursion_depth, predicate }
156 }
157
158 pub fn misc(
159 tcx: TyCtxt<'tcx>,
160 span: Span,
161 body_id: LocalDefId,
162 param_env: ty::ParamEnv<'tcx>,
163 trait_ref: impl Upcast<TyCtxt<'tcx>, O>,
164 ) -> Obligation<'tcx, O> {
165 Obligation::new(tcx, ObligationCause::misc(span, body_id), param_env, trait_ref)
166 }
167
168 pub fn with<P>(
169 &self,
170 tcx: TyCtxt<'tcx>,
171 value: impl Upcast<TyCtxt<'tcx>, P>,
172 ) -> Obligation<'tcx, P> {
173 Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value)
174 }
175}
176
177impl<'tcx> PolyTraitObligation<'tcx> {
178 pub fn polarity(&self) -> ty::PredicatePolarity {
179 self.predicate.skip_binder().polarity
180 }
181
182 pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
183 self.predicate.map_bound(|p| p.self_ty())
184 }
185}