1use crate::hax::prelude::*;
2use crate::hax::sinto_todo;
3
4use rustc_middle::ty;
5
6#[derive(AdtInto)]
10#[args(< S: UnderOwnerState<'tcx>>, from: ty::ExistentialPredicate<'tcx>, state: S as state)]
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum ExistentialPredicate<'tcx> {
13 Trait(ExistentialTraitRef<'tcx>),
16 Projection(ExistentialProjection<'tcx>),
18 AutoTrait(DefId),
20}
21
22#[derive(AdtInto)]
24#[args(< S: UnderOwnerState<'tcx>>, from: ty::ExistentialTraitRef<'tcx>, state: S as state)]
25#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub struct ExistentialTraitRef<'tcx> {
27 pub def_id: DefId,
28 pub args: Vec<GenericArg<'tcx>>,
29}
30
31#[derive(AdtInto)]
33#[args(< S: UnderOwnerState<'tcx>>, from: ty::ExistentialProjection<'tcx>, state: S as state)]
34#[derive(Debug, Clone, PartialEq, Eq, Hash)]
35pub struct ExistentialProjection<'tcx> {
36 pub def_id: DefId,
37 pub args: Vec<GenericArg<'tcx>>,
38 pub term: Term<'tcx>,
39}
40
41impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, GenericPredicate<'tcx>>
42 for rustc_trait_elaboration::DynPredicate<'tcx, DefId>
43{
44 fn sinto(&self, s: &S) -> GenericPredicate<'tcx> {
45 let tcx = s.base().tcx;
46 let pred = &self.predicate;
47 if let Some(projection) = pred.clause.as_projection_clause() {
48 let trait_proof = self
49 .projection_trait_proof
50 .expect("projection predicates should have a trait proof")
51 .sinto(s);
52 let bound_vars = projection.bound_vars().sinto(s);
53 let projection = projection.skip_binder();
54 let alias_ty = projection.projection_term.expect_ty();
55 let Term::Ty(ty) = projection.term.sinto(s) else {
56 unreachable!()
57 };
58 let item = tcx.associated_item(alias_ty_kind_def_id(alias_ty.kind));
59 GenericPredicate {
60 id: pred.id.sinto(s),
61 clause: Clause {
62 kind: Binder {
63 value: ClauseKind::Projection(ProjectionPredicate {
64 trait_proof,
65 assoc_item: AssocItem::sfrom(s, &item),
66 ty,
67 }),
68 bound_vars,
69 },
70 },
71 span: pred.span.sinto(s),
72 }
73 } else {
74 assert!(self.projection_trait_proof.is_none());
75 pred.sinto(s)
76 }
77 }
78}
79
80pub(super) fn resolve_for_dyn<'tcx, S, T, U>(
81 s: &S,
82 epreds: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
83 f: impl FnOnce(&mut PredicateSearcher<'tcx>, ty::Ty<'tcx>) -> T,
84) -> DynBinder<'tcx, U>
85where
86 S: UnderOwnerState<'tcx>,
87 T: SInto<S, U>,
88{
89 s.with_predicate_searcher(|searcher, state| searcher.resolve_for_dyn(state, epreds, f))
90 .sinto(s)
91}
92
93#[derive(AdtInto)]
95#[args(< S: UnderOwnerState<'tcx>>, from: ty::TraitClause<'tcx>, state: S as tcx)]
96#[derive(Debug, Clone, PartialEq, Eq, Hash)]
97pub struct TraitPredicate<'tcx> {
98 pub trait_ref: TraitRef<'tcx>,
99 #[map(*x == ty::ClausePolarity::Positive)]
100 #[from(polarity)]
101 pub is_positive: bool,
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
109pub struct OutlivesPredicate<T> {
110 pub lhs: T,
111 pub rhs: Region,
112}
113
114impl<'tcx, S: UnderOwnerState<'tcx>, T, U> SInto<S, OutlivesPredicate<U>>
115 for ty::OutlivesClause<'tcx, T>
116where
117 T: SInto<S, U>,
118{
119 fn sinto(&self, s: &S) -> OutlivesPredicate<U> where {
120 OutlivesPredicate {
121 lhs: self.0.sinto(s),
122 rhs: self.1.sinto(s),
123 }
124 }
125}
126
127pub type RegionOutlivesPredicate = OutlivesPredicate<Region>;
129pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>>;
131
132#[derive(Debug, Clone, PartialEq, Eq, Hash)]
134pub enum Term<'tcx> {
135 Ty(Ty<'tcx>),
136 Const(ConstantExpr<'tcx>),
137}
138
139impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Term<'tcx>> for ty::Term<'tcx> {
140 fn sinto(&self, s: &S) -> Term<'tcx> {
141 use ty::TermKind;
142 match self.kind() {
143 TermKind::Ty(ty) => Term::Ty(ty.sinto(s)),
144 TermKind::Const(c) => Term::Const(c.sinto(s)),
145 }
146 }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Hash)]
158pub struct ProjectionPredicate<'tcx> {
159 pub trait_proof: TraitProof<'tcx>,
161 pub assoc_item: AssocItem<'tcx>,
163 pub ty: Ty<'tcx>,
165}
166
167impl<'tcx, S: UnderOwnerState<'tcx>> SInto<(S, UnitBinder<'tcx>), ProjectionPredicate<'tcx>>
168 for ty::ProjectionClause<'tcx>
169{
170 fn sinto(&self, s: &(S, UnitBinder<'tcx>)) -> ProjectionPredicate<'tcx> {
171 let tcx = s.base().tcx;
172 let alias_ty = &self.projection_term.expect_ty();
173 let poly_trait_ref = s.1.rebind(alias_ty.trait_ref(tcx));
174 let Term::Ty(ty) = self.term.sinto(s) else {
175 unreachable!()
176 };
177 let item = tcx.associated_item(alias_ty_kind_def_id(alias_ty.kind));
178 ProjectionPredicate {
179 trait_proof: solve_trait(s, poly_trait_ref),
180 assoc_item: AssocItem::sfrom(s, &item),
181 ty,
182 }
183 }
184}
185
186#[derive(AdtInto)]
188#[args(< S: UnderOwnerState<'tcx>>, from: ty::ClauseKind<'tcx>, state: (S, UnitBinder<'tcx>) as tcx)]
189#[derive(Debug, Clone, PartialEq, Eq, Hash)]
190pub enum ClauseKind<'tcx> {
191 Trait(TraitPredicate<'tcx>),
192 RegionOutlives(RegionOutlivesPredicate),
193 TypeOutlives(TypeOutlivesPredicate<'tcx>),
194 Projection(ProjectionPredicate<'tcx>),
195 ConstArgHasType(ConstantExpr<'tcx>, Ty<'tcx>),
196 WellFormed(Term<'tcx>),
197 ConstEvaluatable(ConstantExpr<'tcx>),
198 HostEffect(HostEffectClause),
199 UnstableFeature(Symbol),
200}
201
202sinto_todo!(rustc_middle::ty, HostEffectClause<'tcx>);
203
204#[derive(Debug, Clone, PartialEq, Eq, Hash)]
206pub struct Clause<'tcx> {
207 pub kind: Binder<ClauseKind<'tcx>>,
208}
209
210impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause<'tcx>> for ty::Clause<'tcx> {
211 fn sinto(&self, s: &S) -> Clause<'tcx> {
212 let kind = self.kind().sinto(s);
213 Clause { kind }
214 }
215}
216
217impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Clause<'tcx>> for ty::PolyTraitClause<'tcx> {
218 fn sinto(&self, s: &S) -> Clause<'tcx> {
219 let kind: Binder<_> = self.sinto(s);
220 let kind: Binder<ClauseKind> = kind.map(ClauseKind::Trait);
221 Clause { kind }
222 }
223}
224
225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
227pub struct Predicate<'tcx> {
228 pub kind: Binder<PredicateKind<'tcx>>,
229}
230
231impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, Predicate<'tcx>> for ty::Predicate<'tcx> {
232 fn sinto(&self, s: &S) -> Predicate<'tcx> {
233 let kind = self.kind().sinto(s);
234 Predicate { kind }
235 }
236}
237
238#[derive(AdtInto)]
240#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: traits::ItemPredicateId<DefId>, state: S as s)]
241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
242pub enum GenericPredicateId {
243 Required(DefId, u32),
246 Implied(DefId, u32),
250 Unmapped(u32),
253 TraitSelf,
255}
256
257#[derive(AdtInto)]
258#[args(< S: UnderOwnerState<'tcx>>, from: traits::ItemPredicate<'tcx, DefId>, state: S as s)]
259#[derive(Debug, Clone, PartialEq, Eq, Hash)]
260pub struct GenericPredicate<'tcx> {
261 pub id: GenericPredicateId,
262 pub clause: Clause<'tcx>,
263 pub span: Span,
264}
265
266#[derive(AdtInto)]
268#[args(< S: UnderOwnerState<'tcx>>, from: traits::ItemPredicates<'tcx, DefId>, state: S as s)]
269#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
270pub struct GenericPredicates<'tcx> {
271 pub predicates: Vec<GenericPredicate<'tcx>>,
272}
273
274impl<'tcx> GenericPredicates<'tcx> {
275 pub fn iter(&self) -> impl Iterator<Item = &GenericPredicate<'tcx>> {
276 self.predicates.iter()
277 }
278 pub fn iter_trait_clauses(&self) -> impl Iterator<Item = &GenericPredicate<'tcx>> {
280 self.iter().filter(move |pred| {
281 matches!(pred.clause.kind.hax_skip_binder_ref(), ClauseKind::Trait(_))
282 })
283 }
284}
285
286#[derive(AdtInto)]
288#[args(< S: UnderOwnerState<'tcx>>, from: ty::SubtypePredicate<'tcx>, state: S as tcx)]
289#[derive(Debug, Clone, PartialEq, Eq, Hash)]
290pub struct SubtypePredicate<'tcx> {
291 pub a_is_expected: bool,
292 pub a: Ty<'tcx>,
293 pub b: Ty<'tcx>,
294}
295
296#[derive(AdtInto)]
298#[args(< S: UnderOwnerState<'tcx>>, from: ty::CoercePredicate<'tcx>, state: S as tcx)]
299#[derive(Debug, Clone, PartialEq, Eq, Hash)]
300pub struct CoercePredicate<'tcx> {
301 pub a: Ty<'tcx>,
302 pub b: Ty<'tcx>,
303}
304
305sinto_todo!(rustc_middle::ty, NormalizesTo<'tcx>);
306
307#[derive(AdtInto)]
309#[args(< S: UnderOwnerState<'tcx>>, from: ty::PredicateKind<'tcx>, state: (S, UnitBinder<'tcx>) as tcx)]
310#[derive(Debug, Clone, PartialEq, Eq, Hash)]
311pub enum PredicateKind<'tcx> {
312 Clause(ClauseKind<'tcx>),
313 DynCompatible(DefId),
314 Subtype(SubtypePredicate<'tcx>),
315 Coerce(CoercePredicate<'tcx>),
316 ConstEquate(ConstantExpr<'tcx>, ConstantExpr<'tcx>),
317 Ambiguous,
318 NormalizesTo(NormalizesTo),
319}