1use std::cmp::Ordering;
4
5use intern::{
6 Interned, InternedRef, InternedSlice, InternedSliceRef, impl_internable, impl_slice_internable,
7};
8use macros::{GenericTypeVisitable, TypeFoldable, TypeVisitable};
9use rustc_type_ir::{
10 self as ty, CollectAndApply, EarlyBinder, FlagComputation, Flags, GenericTypeVisitable,
11 PredicatePolarity, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, Upcast,
12 UpcastFrom, WithCachedTypeInfo,
13 elaborate::Elaboratable,
14 error::{ExpectedFound, TypeError},
15 inherent::{IntoKind, SliceLike},
16};
17
18use crate::next_solver::{
19 GenericArg, TraitIdWrapper, default_types, impl_foldable_for_interned_slice,
20 impl_stored_interned_slice, interned_slice,
21};
22
23use super::{Binder, BoundVarKinds, DbInterner, Region, Ty};
24
25pub type BoundExistentialPredicate<'db> = Binder<'db, ExistentialPredicate<'db>>;
26
27pub type TraitRef<'db> = ty::TraitRef<DbInterner<'db>>;
28pub type AliasTerm<'db> = ty::AliasTerm<DbInterner<'db>>;
29pub type ProjectionPredicate<'db> = ty::ProjectionPredicate<DbInterner<'db>>;
30pub type ExistentialPredicate<'db> = ty::ExistentialPredicate<DbInterner<'db>>;
31pub type ExistentialTraitRef<'db> = ty::ExistentialTraitRef<DbInterner<'db>>;
32pub type ExistentialProjection<'db> = ty::ExistentialProjection<DbInterner<'db>>;
33pub type TraitPredicate<'db> = ty::TraitPredicate<DbInterner<'db>>;
34pub type HostEffectPredicate<'db> = ty::HostEffectPredicate<DbInterner<'db>>;
35pub type ClauseKind<'db> = ty::ClauseKind<DbInterner<'db>>;
36pub type PredicateKind<'db> = ty::PredicateKind<DbInterner<'db>>;
37pub type NormalizesTo<'db> = ty::NormalizesTo<DbInterner<'db>>;
38pub type CoercePredicate<'db> = ty::CoercePredicate<DbInterner<'db>>;
39pub type SubtypePredicate<'db> = ty::SubtypePredicate<DbInterner<'db>>;
40pub type OutlivesPredicate<'db, T> = ty::OutlivesPredicate<DbInterner<'db>, T>;
41pub type RegionOutlivesPredicate<'db> = OutlivesPredicate<'db, Region<'db>>;
42pub type TypeOutlivesPredicate<'db> = OutlivesPredicate<'db, Ty<'db>>;
43pub type PolyTraitPredicate<'db> = Binder<'db, TraitPredicate<'db>>;
44pub type PolyRegionOutlivesPredicate<'db> = Binder<'db, RegionOutlivesPredicate<'db>>;
45pub type PolyTypeOutlivesPredicate<'db> = Binder<'db, TypeOutlivesPredicate<'db>>;
46pub type PolySubtypePredicate<'db> = Binder<'db, SubtypePredicate<'db>>;
47pub type PolyCoercePredicate<'db> = Binder<'db, CoercePredicate<'db>>;
48pub type PolyProjectionPredicate<'db> = Binder<'db, ProjectionPredicate<'db>>;
49pub type PolyTraitRef<'db> = Binder<'db, TraitRef<'db>>;
50pub type PolyExistentialTraitRef<'db> = Binder<'db, ExistentialTraitRef<'db>>;
51pub type PolyExistentialProjection<'db> = Binder<'db, ExistentialProjection<'db>>;
52pub type ArgOutlivesPredicate<'db> = OutlivesPredicate<'db, GenericArg<'db>>;
53
54fn stable_cmp_existential_predicate<'db>(
57 a: &ExistentialPredicate<'db>,
58 b: &ExistentialPredicate<'db>,
59) -> Ordering {
60 match (a, b) {
62 (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
63 (ExistentialPredicate::Projection(_a), ExistentialPredicate::Projection(_b)) => {
64 Ordering::Equal
66 }
67 (ExistentialPredicate::AutoTrait(_a), ExistentialPredicate::AutoTrait(_b)) => {
68 Ordering::Equal
70 }
71 (ExistentialPredicate::Trait(_), _) => Ordering::Less,
72 (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => Ordering::Greater,
73 (ExistentialPredicate::Projection(_), _) => Ordering::Less,
74 (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
75 }
76}
77interned_slice!(
78 BoundExistentialPredicatesStorage,
79 BoundExistentialPredicates,
80 StoredBoundExistentialPredicates,
81 bound_existential_predicates,
82 BoundExistentialPredicate<'db>,
83 BoundExistentialPredicate<'static>,
84);
85impl_foldable_for_interned_slice!(BoundExistentialPredicates);
86
87impl<'db> rustc_type_ir::inherent::BoundExistentialPredicates<DbInterner<'db>>
88 for BoundExistentialPredicates<'db>
89{
90 fn principal_def_id(self) -> Option<TraitIdWrapper> {
91 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
92 }
93
94 fn principal(
95 self,
96 ) -> Option<
97 rustc_type_ir::Binder<DbInterner<'db>, rustc_type_ir::ExistentialTraitRef<DbInterner<'db>>>,
98 > {
99 self[0]
100 .map_bound(|this| match this {
101 ExistentialPredicate::Trait(tr) => Some(tr),
102 _ => None,
103 })
104 .transpose()
105 }
106
107 fn auto_traits(self) -> impl IntoIterator<Item = TraitIdWrapper> {
108 self.iter().filter_map(|predicate| match predicate.skip_binder() {
109 ExistentialPredicate::AutoTrait(did) => Some(did),
110 _ => None,
111 })
112 }
113
114 fn projection_bounds(
115 self,
116 ) -> impl IntoIterator<
117 Item = rustc_type_ir::Binder<
118 DbInterner<'db>,
119 rustc_type_ir::ExistentialProjection<DbInterner<'db>>,
120 >,
121 > {
122 self.iter().filter_map(|predicate| {
123 predicate
124 .map_bound(|pred| match pred {
125 ExistentialPredicate::Projection(projection) => Some(projection),
126 _ => None,
127 })
128 .transpose()
129 })
130 }
131}
132
133impl<'db> rustc_type_ir::relate::Relate<DbInterner<'db>> for BoundExistentialPredicates<'db> {
134 fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
135 relation: &mut R,
136 a: Self,
137 b: Self,
138 ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
139 let interner = relation.cx();
140
141 let mut a_v: Vec<_> = a.into_iter().collect();
143 let mut b_v: Vec<_> = b.into_iter().collect();
144 a_v.sort_by(|a, b| {
146 stable_cmp_existential_predicate(a.as_ref().skip_binder(), b.as_ref().skip_binder())
147 });
148 a_v.dedup();
149 b_v.sort_by(|a, b| {
150 stable_cmp_existential_predicate(a.as_ref().skip_binder(), b.as_ref().skip_binder())
151 });
152 b_v.dedup();
153 if a_v.len() != b_v.len() {
154 return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b)));
155 }
156
157 let v = std::iter::zip(a_v, b_v).map(
158 |(ep_a, ep_b): (
159 Binder<'_, ty::ExistentialPredicate<_>>,
160 Binder<'_, ty::ExistentialPredicate<_>>,
161 )| {
162 match (ep_a.skip_binder(), ep_b.skip_binder()) {
163 (ty::ExistentialPredicate::Trait(a), ty::ExistentialPredicate::Trait(b)) => {
164 Ok(ep_a.rebind(ty::ExistentialPredicate::Trait(
165 relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
166 )))
167 }
168 (
169 ty::ExistentialPredicate::Projection(a),
170 ty::ExistentialPredicate::Projection(b),
171 ) => Ok(ep_a.rebind(ty::ExistentialPredicate::Projection(
172 relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
173 ))),
174 (
175 ty::ExistentialPredicate::AutoTrait(a),
176 ty::ExistentialPredicate::AutoTrait(b),
177 ) if a == b => Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))),
178 _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))),
179 }
180 },
181 );
182
183 BoundExistentialPredicates::new_from_iter(interner, v)
184 }
185}
186
187#[derive(Clone, Copy, PartialEq, Eq, Hash)]
188pub struct Predicate<'db> {
189 interned: InternedRef<'db, PredicateInterned>,
190}
191
192#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)]
193pub(super) struct PredicateInterned(WithCachedTypeInfo<Binder<'static, PredicateKind<'static>>>);
194
195impl_internable!(gc; PredicateInterned);
196
197const _: () = {
198 const fn is_copy<T: Copy>() {}
199 is_copy::<Predicate<'static>>();
200};
201
202impl<'db> Predicate<'db> {
203 pub fn new(_interner: DbInterner<'db>, kind: Binder<'db, PredicateKind<'db>>) -> Self {
204 let kind = unsafe {
205 std::mem::transmute::<
206 Binder<'db, PredicateKind<'db>>,
207 Binder<'static, PredicateKind<'static>>,
208 >(kind)
209 };
210 let flags = FlagComputation::for_predicate(kind);
211 let cached = WithCachedTypeInfo {
212 internee: kind,
213 flags: flags.flags,
214 outer_exclusive_binder: flags.outer_exclusive_binder,
215 };
216 Self { interned: Interned::new_gc(PredicateInterned(cached)) }
217 }
218
219 pub fn inner(&self) -> &WithCachedTypeInfo<Binder<'db, PredicateKind<'db>>> {
220 let inner = &self.interned.0;
221 unsafe {
222 std::mem::transmute::<
223 &WithCachedTypeInfo<Binder<'static, PredicateKind<'static>>>,
224 &WithCachedTypeInfo<Binder<'db, PredicateKind<'db>>>,
225 >(inner)
226 }
227 }
228
229 pub fn flip_polarity(self, interner: DbInterner<'db>) -> Option<Predicate<'db>> {
233 let kind = self
234 .kind()
235 .map_bound(|kind| match kind {
236 PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
237 trait_ref,
238 polarity,
239 })) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
240 trait_ref,
241 polarity: polarity.flip(),
242 }))),
243
244 _ => None,
245 })
246 .transpose()?;
247
248 Some(Predicate::new(interner, kind))
249 }
250}
251
252impl<'db> std::fmt::Debug for Predicate<'db> {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 self.kind().fmt(f)
255 }
256}
257
258#[derive(Clone, Copy, PartialEq, Eq, Hash, GenericTypeVisitable)]
259pub struct ClausesCachedTypeInfo(WithCachedTypeInfo<()>);
260
261impl_slice_internable!(gc; ClausesStorage, ClausesCachedTypeInfo, Clause<'static>);
262impl_stored_interned_slice!(ClausesStorage, Clauses, StoredClauses);
263
264#[derive(Clone, Copy, PartialEq, Eq, Hash)]
265pub struct Clauses<'db> {
266 interned: InternedSliceRef<'db, ClausesStorage>,
267}
268
269impl<'db> std::fmt::Debug for Clauses<'db> {
270 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
271 self.as_slice().fmt(fmt)
272 }
273}
274
275impl<'db> Clauses<'db> {
276 #[inline]
277 pub fn empty() -> Self {
278 default_types().empty.clauses
279 }
280
281 #[inline]
282 pub fn new_from_slice(slice: &[Clause<'db>]) -> Self {
283 let slice = unsafe { ::std::mem::transmute::<&[Clause<'db>], &[Clause<'static>]>(slice) };
284 let flags = FlagComputation::<DbInterner<'db>>::for_clauses(slice);
285 let flags = ClausesCachedTypeInfo(WithCachedTypeInfo {
286 internee: (),
287 flags: flags.flags,
288 outer_exclusive_binder: flags.outer_exclusive_binder,
289 });
290 Self { interned: InternedSlice::from_header_and_slice(flags, slice) }
291 }
292
293 #[inline]
294 pub fn new_from_iter<I, T>(_interner: DbInterner<'db>, args: I) -> T::Output
295 where
296 I: IntoIterator<Item = T>,
297 T: CollectAndApply<Clause<'db>, Self>,
298 {
299 CollectAndApply::collect_and_apply(args.into_iter(), Self::new_from_slice)
300 }
301
302 #[inline]
303 pub fn as_slice(self) -> &'db [Clause<'db>] {
304 let slice = &self.interned.get().slice;
305 unsafe { ::std::mem::transmute::<&[Clause<'static>], &[Clause<'db>]>(slice) }
306 }
307
308 #[inline]
309 pub fn iter(self) -> ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>> {
310 self.as_slice().iter().copied()
311 }
312
313 #[inline]
314 pub fn len(self) -> usize {
315 self.as_slice().len()
316 }
317
318 #[inline]
319 pub fn is_empty(self) -> bool {
320 self.as_slice().is_empty()
321 }
322}
323
324impl Default for Clauses<'_> {
325 #[inline]
326 fn default() -> Self {
327 Self::empty()
328 }
329}
330
331impl<'db> IntoIterator for Clauses<'db> {
332 type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>>;
333 type Item = Clause<'db>;
334 #[inline]
335 fn into_iter(self) -> Self::IntoIter {
336 self.iter()
337 }
338}
339
340impl<'db> std::ops::Deref for Clauses<'db> {
341 type Target = [Clause<'db>];
342
343 #[inline]
344 fn deref(&self) -> &Self::Target {
345 (*self).as_slice()
346 }
347}
348
349impl<'db> rustc_type_ir::inherent::SliceLike for Clauses<'db> {
350 type Item = Clause<'db>;
351
352 type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>>;
353
354 #[inline]
355 fn iter(self) -> Self::IntoIter {
356 self.iter()
357 }
358
359 #[inline]
360 fn as_slice(&self) -> &[Self::Item] {
361 (*self).as_slice()
362 }
363}
364
365impl<'db> rustc_type_ir::inherent::Clauses<DbInterner<'db>> for Clauses<'db> {}
366
367impl<'db> rustc_type_ir::TypeSuperFoldable<DbInterner<'db>> for Clauses<'db> {
368 fn try_super_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
369 self,
370 folder: &mut F,
371 ) -> Result<Self, F::Error> {
372 Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.try_fold_with(folder)))
373 }
374
375 fn super_fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
376 self,
377 folder: &mut F,
378 ) -> Self {
379 Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.fold_with(folder)))
380 }
381}
382
383impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for Clauses<'db> {
384 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
385 self,
386 folder: &mut F,
387 ) -> Result<Self, F::Error> {
388 self.try_super_fold_with(folder)
389 }
390 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
391 self.super_fold_with(folder)
392 }
393}
394
395impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for Clauses<'db> {
396 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
397 &self,
398 visitor: &mut V,
399 ) -> V::Result {
400 use rustc_ast_ir::visit::VisitorResult;
401 rustc_ast_ir::walk_visitable_list!(visitor, self.iter());
402 V::Result::output()
403 }
404}
405
406impl<'db, V: super::WorldExposer> rustc_type_ir::GenericTypeVisitable<V> for Clauses<'db> {
407 fn generic_visit_with(&self, visitor: &mut V) {
408 if visitor.on_interned_slice(self.interned).is_continue() {
409 self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor));
410 }
411 }
412}
413
414impl<'db> rustc_type_ir::Flags for Clauses<'db> {
415 #[inline]
416 fn flags(&self) -> rustc_type_ir::TypeFlags {
417 self.interned.header.header.0.flags
418 }
419
420 #[inline]
421 fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
422 self.interned.header.header.0.outer_exclusive_binder
423 }
424}
425
426impl<'db> rustc_type_ir::TypeSuperVisitable<DbInterner<'db>> for Clauses<'db> {
427 fn super_visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
428 &self,
429 visitor: &mut V,
430 ) -> V::Result {
431 self.as_slice().visit_with(visitor)
432 }
433}
434
435#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, GenericTypeVisitable)] pub struct Clause<'db>(pub(crate) Predicate<'db>);
437
438#[derive(
440 Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable, GenericTypeVisitable,
441)]
442pub struct ParamEnv<'db> {
443 pub(crate) clauses: Clauses<'db>,
444}
445
446impl<'db> ParamEnv<'db> {
447 #[inline]
448 pub fn empty() -> Self {
449 ParamEnv { clauses: Clauses::empty() }
450 }
451
452 pub fn clauses(self) -> Clauses<'db> {
453 self.clauses
454 }
455}
456
457impl<'db> rustc_type_ir::inherent::ParamEnv<DbInterner<'db>> for ParamEnv<'db> {
458 fn caller_bounds(self) -> impl rustc_type_ir::inherent::SliceLike<Item = Clause<'db>> {
459 self.clauses
460 }
461}
462
463#[derive(Clone, Debug, PartialEq, Eq, Hash)]
464pub struct ParamEnvAnd<'db, T> {
465 pub param_env: ParamEnv<'db>,
466 pub value: T,
467}
468
469impl<'db, T> ParamEnvAnd<'db, T> {
470 pub fn into_parts(self) -> (ParamEnv<'db>, T) {
471 (self.param_env, self.value)
472 }
473}
474
475impl<'db> TypeVisitable<DbInterner<'db>> for Predicate<'db> {
476 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
477 &self,
478 visitor: &mut V,
479 ) -> V::Result {
480 visitor.visit_predicate(*self)
481 }
482}
483
484impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Predicate<'db> {
485 fn generic_visit_with(&self, visitor: &mut V) {
486 if visitor.on_interned(self.interned).is_continue() {
487 self.kind().generic_visit_with(visitor);
488 }
489 }
490}
491
492impl<'db> TypeSuperVisitable<DbInterner<'db>> for Predicate<'db> {
493 fn super_visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
494 &self,
495 visitor: &mut V,
496 ) -> V::Result {
497 (*self).kind().visit_with(visitor)
498 }
499}
500
501impl<'db> TypeFoldable<DbInterner<'db>> for Predicate<'db> {
502 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
503 self,
504 folder: &mut F,
505 ) -> Result<Self, F::Error> {
506 folder.try_fold_predicate(self)
507 }
508 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
509 folder.fold_predicate(self)
510 }
511}
512
513impl<'db> TypeSuperFoldable<DbInterner<'db>> for Predicate<'db> {
514 fn try_super_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
515 self,
516 folder: &mut F,
517 ) -> Result<Self, F::Error> {
518 let new = self.kind().try_fold_with(folder)?;
519 Ok(Predicate::new(folder.cx(), new))
520 }
521 fn super_fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
522 self,
523 folder: &mut F,
524 ) -> Self {
525 let new = self.kind().fold_with(folder);
526 Predicate::new(folder.cx(), new)
527 }
528}
529
530impl<'db> Elaboratable<DbInterner<'db>> for Predicate<'db> {
531 fn predicate(&self) -> <DbInterner<'db> as rustc_type_ir::Interner>::Predicate {
532 *self
533 }
534
535 fn child(&self, clause: <DbInterner<'db> as rustc_type_ir::Interner>::Clause) -> Self {
536 clause.as_predicate()
537 }
538
539 fn child_with_derived_cause(
540 &self,
541 clause: <DbInterner<'db> as rustc_type_ir::Interner>::Clause,
542 _span: <DbInterner<'db> as rustc_type_ir::Interner>::Span,
543 _parent_trait_pred: rustc_type_ir::Binder<
544 DbInterner<'db>,
545 rustc_type_ir::TraitPredicate<DbInterner<'db>>,
546 >,
547 _index: usize,
548 ) -> Self {
549 clause.as_predicate()
550 }
551}
552
553impl<'db> Flags for Predicate<'db> {
554 fn flags(&self) -> rustc_type_ir::TypeFlags {
555 self.inner().flags
556 }
557
558 fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
559 self.inner().outer_exclusive_binder
560 }
561}
562
563impl<'db> IntoKind for Predicate<'db> {
564 type Kind = Binder<'db, PredicateKind<'db>>;
565
566 fn kind(self) -> Self::Kind {
567 self.inner().internee
568 }
569}
570
571impl<'db> UpcastFrom<DbInterner<'db>, ty::PredicateKind<DbInterner<'db>>> for Predicate<'db> {
572 fn upcast_from(from: ty::PredicateKind<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
573 Binder::dummy(from).upcast(interner)
574 }
575}
576impl<'db>
577 UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::PredicateKind<DbInterner<'db>>>>
578 for Predicate<'db>
579{
580 fn upcast_from(
581 from: ty::Binder<DbInterner<'db>, ty::PredicateKind<DbInterner<'db>>>,
582 interner: DbInterner<'db>,
583 ) -> Self {
584 Predicate::new(interner, from)
585 }
586}
587impl<'db> UpcastFrom<DbInterner<'db>, ty::ClauseKind<DbInterner<'db>>> for Predicate<'db> {
588 fn upcast_from(from: ty::ClauseKind<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
589 Binder::dummy(PredicateKind::Clause(from)).upcast(interner)
590 }
591}
592impl<'db> UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::ClauseKind<DbInterner<'db>>>>
593 for Predicate<'db>
594{
595 fn upcast_from(
596 from: ty::Binder<DbInterner<'db>, ty::ClauseKind<DbInterner<'db>>>,
597 interner: DbInterner<'db>,
598 ) -> Self {
599 from.map_bound(PredicateKind::Clause).upcast(interner)
600 }
601}
602impl<'db> UpcastFrom<DbInterner<'db>, Clause<'db>> for Predicate<'db> {
603 fn upcast_from(from: Clause<'db>, _interner: DbInterner<'db>) -> Self {
604 from.0
605 }
606}
607impl<'db> UpcastFrom<DbInterner<'db>, ty::NormalizesTo<DbInterner<'db>>> for Predicate<'db> {
608 fn upcast_from(from: ty::NormalizesTo<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
609 PredicateKind::NormalizesTo(from).upcast(interner)
610 }
611}
612impl<'db> UpcastFrom<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>> for Predicate<'db> {
613 fn upcast_from(from: ty::TraitRef<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
614 Binder::dummy(from).upcast(interner)
615 }
616}
617impl<'db> UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>>>
618 for Predicate<'db>
619{
620 fn upcast_from(
621 from: ty::Binder<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>>,
622 interner: DbInterner<'db>,
623 ) -> Self {
624 from.map_bound(|trait_ref| TraitPredicate {
625 trait_ref,
626 polarity: PredicatePolarity::Positive,
627 })
628 .upcast(interner)
629 }
630}
631impl<'db> UpcastFrom<DbInterner<'db>, Binder<'db, ty::TraitPredicate<DbInterner<'db>>>>
632 for Predicate<'db>
633{
634 fn upcast_from(
635 from: Binder<'db, ty::TraitPredicate<DbInterner<'db>>>,
636 interner: DbInterner<'db>,
637 ) -> Self {
638 from.map_bound(|it| PredicateKind::Clause(ClauseKind::Trait(it))).upcast(interner)
639 }
640}
641impl<'db> UpcastFrom<DbInterner<'db>, Binder<'db, ProjectionPredicate<'db>>> for Predicate<'db> {
642 fn upcast_from(from: Binder<'db, ProjectionPredicate<'db>>, interner: DbInterner<'db>) -> Self {
643 from.map_bound(|it| PredicateKind::Clause(ClauseKind::Projection(it))).upcast(interner)
644 }
645}
646impl<'db> UpcastFrom<DbInterner<'db>, ProjectionPredicate<'db>> for Predicate<'db> {
647 fn upcast_from(from: ProjectionPredicate<'db>, interner: DbInterner<'db>) -> Self {
648 PredicateKind::Clause(ClauseKind::Projection(from)).upcast(interner)
649 }
650}
651impl<'db> UpcastFrom<DbInterner<'db>, ty::TraitPredicate<DbInterner<'db>>> for Predicate<'db> {
652 fn upcast_from(from: ty::TraitPredicate<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
653 PredicateKind::Clause(ClauseKind::Trait(from)).upcast(interner)
654 }
655}
656impl<'db> UpcastFrom<DbInterner<'db>, ty::OutlivesPredicate<DbInterner<'db>, Ty<'db>>>
657 for Predicate<'db>
658{
659 fn upcast_from(
660 from: ty::OutlivesPredicate<DbInterner<'db>, Ty<'db>>,
661 interner: DbInterner<'db>,
662 ) -> Self {
663 PredicateKind::Clause(ClauseKind::TypeOutlives(from)).upcast(interner)
664 }
665}
666impl<'db> UpcastFrom<DbInterner<'db>, ty::OutlivesPredicate<DbInterner<'db>, Region<'db>>>
667 for Predicate<'db>
668{
669 fn upcast_from(
670 from: ty::OutlivesPredicate<DbInterner<'db>, Region<'db>>,
671 interner: DbInterner<'db>,
672 ) -> Self {
673 PredicateKind::Clause(ClauseKind::RegionOutlives(from)).upcast(interner)
674 }
675}
676impl<'db> UpcastFrom<DbInterner<'db>, ty::OutlivesPredicate<DbInterner<'db>, Ty<'db>>>
677 for Clause<'db>
678{
679 fn upcast_from(
680 from: ty::OutlivesPredicate<DbInterner<'db>, Ty<'db>>,
681 interner: DbInterner<'db>,
682 ) -> Self {
683 Clause(from.upcast(interner))
684 }
685}
686impl<'db> UpcastFrom<DbInterner<'db>, ty::OutlivesPredicate<DbInterner<'db>, Region<'db>>>
687 for Clause<'db>
688{
689 fn upcast_from(
690 from: ty::OutlivesPredicate<DbInterner<'db>, Region<'db>>,
691 interner: DbInterner<'db>,
692 ) -> Self {
693 Clause(from.upcast(interner))
694 }
695}
696
697impl<'db> UpcastFrom<DbInterner<'db>, PolyRegionOutlivesPredicate<'db>> for Predicate<'db> {
698 fn upcast_from(from: PolyRegionOutlivesPredicate<'db>, tcx: DbInterner<'db>) -> Self {
699 from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx)
700 }
701}
702
703impl<'db> rustc_type_ir::inherent::Predicate<DbInterner<'db>> for Predicate<'db> {
704 fn as_clause(self) -> Option<<DbInterner<'db> as rustc_type_ir::Interner>::Clause> {
705 match self.kind().skip_binder() {
706 PredicateKind::Clause(..) => Some(self.expect_clause()),
707 _ => None,
708 }
709 }
710}
711
712impl<'db> Predicate<'db> {
713 pub fn as_trait_clause(self) -> Option<PolyTraitPredicate<'db>> {
714 let predicate = self.kind();
715 match predicate.skip_binder() {
716 PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
717 _ => None,
718 }
719 }
720
721 pub fn as_projection_clause(self) -> Option<PolyProjectionPredicate<'db>> {
722 let predicate = self.kind();
723 match predicate.skip_binder() {
724 PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
725 _ => None,
726 }
727 }
728
729 pub fn as_clause(self) -> Option<Clause<'db>> {
731 match self.kind().skip_binder() {
732 PredicateKind::Clause(..) => Some(self.expect_clause()),
733 _ => None,
734 }
735 }
736
737 pub fn expect_clause(self) -> Clause<'db> {
739 match self.kind().skip_binder() {
740 PredicateKind::Clause(..) => Clause(self),
741 _ => panic!("{self:?} is not a clause"),
742 }
743 }
744}
745
746impl<'db> TypeVisitable<DbInterner<'db>> for Clause<'db> {
747 fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
748 &self,
749 visitor: &mut V,
750 ) -> V::Result {
751 visitor.visit_predicate((*self).as_predicate())
752 }
753}
754
755impl<'db> TypeFoldable<DbInterner<'db>> for Clause<'db> {
756 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
757 self,
758 folder: &mut F,
759 ) -> Result<Self, F::Error> {
760 Ok(folder.try_fold_predicate(self.as_predicate())?.expect_clause())
761 }
762 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
763 folder.fold_predicate(self.as_predicate()).expect_clause()
764 }
765}
766
767impl<'db> IntoKind for Clause<'db> {
768 type Kind = Binder<'db, ClauseKind<'db>>;
769
770 fn kind(self) -> Self::Kind {
771 self.0.kind().map_bound(|pk| match pk {
772 PredicateKind::Clause(kind) => kind,
773 _ => unreachable!(),
774 })
775 }
776}
777
778impl<'db> Clause<'db> {
779 pub fn as_predicate(self) -> Predicate<'db> {
780 self.0
781 }
782}
783
784impl<'db> Elaboratable<DbInterner<'db>> for Clause<'db> {
785 fn predicate(&self) -> <DbInterner<'db> as rustc_type_ir::Interner>::Predicate {
786 self.0
787 }
788
789 fn child(&self, clause: <DbInterner<'db> as rustc_type_ir::Interner>::Clause) -> Self {
790 clause
791 }
792
793 fn child_with_derived_cause(
794 &self,
795 clause: <DbInterner<'db> as rustc_type_ir::Interner>::Clause,
796 _span: <DbInterner<'db> as rustc_type_ir::Interner>::Span,
797 _parent_trait_pred: rustc_type_ir::Binder<
798 DbInterner<'db>,
799 rustc_type_ir::TraitPredicate<DbInterner<'db>>,
800 >,
801 _index: usize,
802 ) -> Self {
803 clause
804 }
805}
806
807impl<'db> UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::ClauseKind<DbInterner<'db>>>>
808 for Clause<'db>
809{
810 fn upcast_from(
811 from: ty::Binder<DbInterner<'db>, ty::ClauseKind<DbInterner<'db>>>,
812 interner: DbInterner<'db>,
813 ) -> Self {
814 Clause(from.map_bound(PredicateKind::Clause).upcast(interner))
815 }
816}
817impl<'db> UpcastFrom<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>> for Clause<'db> {
818 fn upcast_from(from: ty::TraitRef<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
819 Clause(from.upcast(interner))
820 }
821}
822impl<'db> UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>>>
823 for Clause<'db>
824{
825 fn upcast_from(
826 from: ty::Binder<DbInterner<'db>, ty::TraitRef<DbInterner<'db>>>,
827 interner: DbInterner<'db>,
828 ) -> Self {
829 Clause(from.upcast(interner))
830 }
831}
832impl<'db> UpcastFrom<DbInterner<'db>, ty::TraitPredicate<DbInterner<'db>>> for Clause<'db> {
833 fn upcast_from(from: ty::TraitPredicate<DbInterner<'db>>, interner: DbInterner<'db>) -> Self {
834 Clause(from.upcast(interner))
835 }
836}
837impl<'db>
838 UpcastFrom<DbInterner<'db>, ty::Binder<DbInterner<'db>, ty::TraitPredicate<DbInterner<'db>>>>
839 for Clause<'db>
840{
841 fn upcast_from(
842 from: ty::Binder<DbInterner<'db>, ty::TraitPredicate<DbInterner<'db>>>,
843 interner: DbInterner<'db>,
844 ) -> Self {
845 Clause(from.upcast(interner))
846 }
847}
848impl<'db> UpcastFrom<DbInterner<'db>, ty::ProjectionPredicate<DbInterner<'db>>> for Clause<'db> {
849 fn upcast_from(
850 from: ty::ProjectionPredicate<DbInterner<'db>>,
851 interner: DbInterner<'db>,
852 ) -> Self {
853 Clause(from.upcast(interner))
854 }
855}
856impl<'db>
857 UpcastFrom<
858 DbInterner<'db>,
859 ty::Binder<DbInterner<'db>, ty::ProjectionPredicate<DbInterner<'db>>>,
860 > for Clause<'db>
861{
862 fn upcast_from(
863 from: ty::Binder<DbInterner<'db>, ty::ProjectionPredicate<DbInterner<'db>>>,
864 interner: DbInterner<'db>,
865 ) -> Self {
866 Clause(from.upcast(interner))
867 }
868}
869
870impl<'db> rustc_type_ir::inherent::Clause<DbInterner<'db>> for Clause<'db> {
871 fn as_predicate(self) -> <DbInterner<'db> as rustc_type_ir::Interner>::Predicate {
872 self.0
873 }
874
875 fn instantiate_supertrait(
876 self,
877 cx: DbInterner<'db>,
878 trait_ref: rustc_type_ir::Binder<DbInterner<'db>, rustc_type_ir::TraitRef<DbInterner<'db>>>,
879 ) -> Self {
880 tracing::debug!(?self, ?trait_ref);
881 let bound_pred = self.kind();
883 let pred_bound_vars = bound_pred.bound_vars();
884 let trait_bound_vars = trait_ref.bound_vars();
885 let shifted_pred =
887 cx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
888 let new = EarlyBinder::bind(shifted_pred)
890 .instantiate(cx, trait_ref.skip_binder().args)
891 .skip_norm_wip();
892 let bound_vars =
894 BoundVarKinds::new_from_iter(cx, trait_bound_vars.iter().chain(pred_bound_vars.iter()));
895
896 let predicate: Predicate<'db> =
897 ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars).upcast(cx);
898 predicate.expect_clause()
899 }
900}