1use std::fmt;
2use std::hash::Hash;
3
4use derive_where::derive_where;
5#[cfg(feature = "nightly")]
6use rustc_macros::{
7 Decodable, Decodable_NoContext, Encodable, Encodable_NoContext, HashStable_NoContext,
8};
9use rustc_type_ir_macros::{
10 GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
11};
12
13use crate::inherent::*;
14use crate::lift::Lift;
15use crate::upcast::{Upcast, UpcastFrom};
16use crate::visit::TypeVisitableExt as _;
17use crate::{self as ty, Interner};
18
19#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)]
21#[derive_where(Copy; I: Interner, A: Copy)]
22#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)]
23#[cfg_attr(
24 feature = "nightly",
25 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
26)]
27pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
28
29impl<I: Interner, A: Eq> Eq for OutlivesPredicate<I, A> {}
30
31impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A>
34where
35 A: Lift<U>,
36 I::Region: Lift<U, Lifted = U::Region>,
37{
38 type Lifted = OutlivesPredicate<U, A::Lifted>;
39
40 fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
41 Some(OutlivesPredicate(self.0.lift_to_interner(cx)?, self.1.lift_to_interner(cx)?))
42 }
43}
44
45#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
57#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
58#[cfg_attr(
59 feature = "nightly",
60 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
61)]
62pub struct TraitRef<I: Interner> {
63 pub def_id: I::TraitId,
64 pub args: I::GenericArgs,
65 _use_trait_ref_new_instead: (),
68}
69
70impl<I: Interner> Eq for TraitRef<I> {}
71
72impl<I: Interner> TraitRef<I> {
73 pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
74 interner.debug_assert_args_compatible(trait_def_id.into(), args);
75 Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
76 }
77
78 pub fn new(
79 interner: I,
80 trait_def_id: I::TraitId,
81 args: impl IntoIterator<Item: Into<I::GenericArg>>,
82 ) -> Self {
83 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
84 Self::new_from_args(interner, trait_def_id, args)
85 }
86
87 pub fn from_assoc(interner: I, trait_id: I::TraitId, args: I::GenericArgs) -> TraitRef<I> {
88 let generics = interner.generics_of(trait_id.into());
89 TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
90 }
91
92 pub fn identity(interner: I, def_id: I::TraitId) -> TraitRef<I> {
95 TraitRef::new_from_args(
96 interner,
97 def_id,
98 I::GenericArgs::identity_for_item(interner, def_id.into()),
99 )
100 }
101
102 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
103 TraitRef::new(
104 interner,
105 self.def_id,
106 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
107 )
108 }
109
110 #[inline]
111 pub fn self_ty(&self) -> I::Ty {
112 self.args.type_at(0)
113 }
114}
115
116impl<I: Interner> ty::Binder<I, TraitRef<I>> {
117 pub fn self_ty(&self) -> ty::Binder<I, I::Ty> {
118 self.map_bound_ref(|tr| tr.self_ty())
119 }
120
121 pub fn def_id(&self) -> I::TraitId {
122 self.skip_binder().def_id
123 }
124
125 pub fn to_host_effect_clause(self, cx: I, constness: BoundConstness) -> I::Clause {
126 self.map_bound(|trait_ref| {
127 ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
128 })
129 .upcast(cx)
130 }
131}
132
133#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
134#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
135#[cfg_attr(
136 feature = "nightly",
137 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
138)]
139pub struct TraitPredicate<I: Interner> {
140 pub trait_ref: TraitRef<I>,
141
142 pub polarity: PredicatePolarity,
148}
149
150impl<I: Interner> Eq for TraitPredicate<I> {}
151
152impl<I: Interner> TraitPredicate<I> {
153 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
154 Self {
155 trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty),
156 polarity: self.polarity,
157 }
158 }
159
160 pub fn def_id(self) -> I::TraitId {
161 self.trait_ref.def_id
162 }
163
164 pub fn self_ty(self) -> I::Ty {
165 self.trait_ref.self_ty()
166 }
167}
168
169impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
170 pub fn def_id(self) -> I::TraitId {
171 self.skip_binder().def_id()
173 }
174
175 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
176 self.map_bound(|trait_ref| trait_ref.self_ty())
177 }
178
179 #[inline]
180 pub fn polarity(self) -> PredicatePolarity {
181 self.skip_binder().polarity
182 }
183}
184
185impl<I: Interner> UpcastFrom<I, TraitRef<I>> for TraitPredicate<I> {
186 fn upcast_from(from: TraitRef<I>, _tcx: I) -> Self {
187 TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
188 }
189}
190
191impl<I: Interner> UpcastFrom<I, ty::Binder<I, TraitRef<I>>> for ty::Binder<I, TraitPredicate<I>> {
192 fn upcast_from(from: ty::Binder<I, TraitRef<I>>, _tcx: I) -> Self {
193 from.map_bound(|trait_ref| TraitPredicate {
194 trait_ref,
195 polarity: PredicatePolarity::Positive,
196 })
197 }
198}
199
200impl<I: Interner> fmt::Debug for TraitPredicate<I> {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
203 }
204}
205
206#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
207#[cfg_attr(
208 feature = "nightly",
209 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
210)]
211pub enum ImplPolarity {
212 Positive,
214 Negative,
216 Reservation,
221}
222
223impl fmt::Display for ImplPolarity {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 match self {
226 Self::Positive => f.write_str("positive"),
227 Self::Negative => f.write_str("negative"),
228 Self::Reservation => f.write_str("reservation"),
229 }
230 }
231}
232
233impl ImplPolarity {
234 pub fn as_str(self) -> &'static str {
236 match self {
237 Self::Positive => "",
238 Self::Negative => "!",
239 Self::Reservation => "",
240 }
241 }
242}
243
244#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
248#[cfg_attr(
249 feature = "nightly",
250 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
251)]
252pub enum PredicatePolarity {
253 Positive,
255 Negative,
257}
258
259impl PredicatePolarity {
260 pub fn flip(&self) -> PredicatePolarity {
262 match self {
263 PredicatePolarity::Positive => PredicatePolarity::Negative,
264 PredicatePolarity::Negative => PredicatePolarity::Positive,
265 }
266 }
267}
268
269impl fmt::Display for PredicatePolarity {
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 match self {
272 Self::Positive => f.write_str("positive"),
273 Self::Negative => f.write_str("negative"),
274 }
275 }
276}
277
278#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
279#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
280#[cfg_attr(
281 feature = "nightly",
282 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
283)]
284pub enum ExistentialPredicate<I: Interner> {
285 Trait(ExistentialTraitRef<I>),
287 Projection(ExistentialProjection<I>),
289 AutoTrait(I::TraitId),
291}
292
293impl<I: Interner> Eq for ExistentialPredicate<I> {}
294
295impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
296 pub fn def_id(&self) -> I::DefId {
297 match self.skip_binder() {
298 ExistentialPredicate::Trait(tr) => tr.def_id.into(),
299 ExistentialPredicate::Projection(p) => p.def_id.into(),
300 ExistentialPredicate::AutoTrait(did) => did.into(),
301 }
302 }
303 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause {
307 match self.skip_binder() {
308 ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx),
309 ExistentialPredicate::Projection(p) => {
310 self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
311 }
312 ExistentialPredicate::AutoTrait(did) => {
313 let generics = cx.generics_of(did.into());
314 let trait_ref = if generics.count() == 1 {
315 ty::TraitRef::new(cx, did, [self_ty])
316 } else {
317 let err_args =
320 GenericArgs::extend_with_error(cx, did.into(), &[self_ty.into()]);
321 ty::TraitRef::new_from_args(cx, did, err_args)
322 };
323 self.rebind(trait_ref).upcast(cx)
324 }
325 }
326 }
327}
328
329#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
337#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
338#[cfg_attr(
339 feature = "nightly",
340 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
341)]
342pub struct ExistentialTraitRef<I: Interner> {
343 pub def_id: I::TraitId,
344 pub args: I::GenericArgs,
345 _use_existential_trait_ref_new_instead: (),
348}
349
350impl<I: Interner> Eq for ExistentialTraitRef<I> {}
351
352impl<I: Interner> ExistentialTraitRef<I> {
353 pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
354 interner.debug_assert_existential_args_compatible(trait_def_id.into(), args);
355 Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
356 }
357
358 pub fn new(
359 interner: I,
360 trait_def_id: I::TraitId,
361 args: impl IntoIterator<Item: Into<I::GenericArg>>,
362 ) -> Self {
363 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
364 Self::new_from_args(interner, trait_def_id, args)
365 }
366
367 pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
368 trait_ref.args.type_at(0);
370
371 ExistentialTraitRef {
372 def_id: trait_ref.def_id,
373 args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
374 _use_existential_trait_ref_new_instead: (),
375 }
376 }
377
378 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
383 TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
387 }
388}
389
390impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
391 pub fn def_id(&self) -> I::TraitId {
392 self.skip_binder().def_id
393 }
394
395 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
400 self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
401 }
402}
403
404#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
406#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
407#[cfg_attr(
408 feature = "nightly",
409 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
410)]
411pub struct ExistentialProjection<I: Interner> {
412 pub def_id: I::DefId,
413 pub args: I::GenericArgs,
414 pub term: I::Term,
415
416 use_existential_projection_new_instead: (),
419}
420
421impl<I: Interner> Eq for ExistentialProjection<I> {}
422
423impl<I: Interner> ExistentialProjection<I> {
424 pub fn new_from_args(
425 interner: I,
426 def_id: I::DefId,
427 args: I::GenericArgs,
428 term: I::Term,
429 ) -> ExistentialProjection<I> {
430 interner.debug_assert_existential_args_compatible(def_id, args);
431 Self { def_id, args, term, use_existential_projection_new_instead: () }
432 }
433
434 pub fn new(
435 interner: I,
436 def_id: I::DefId,
437 args: impl IntoIterator<Item: Into<I::GenericArg>>,
438 term: I::Term,
439 ) -> ExistentialProjection<I> {
440 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
441 Self::new_from_args(interner, def_id, args, term)
442 }
443
444 pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
449 let def_id = interner.parent(self.def_id);
450 let args_count = interner.generics_of(def_id).count() - 1;
451 let args = interner.mk_args(&self.args.as_slice()[..args_count]);
452 ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args)
453 }
454
455 pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
456 debug_assert!(!self_ty.has_escaping_bound_vars());
458
459 ProjectionPredicate {
460 projection_term: AliasTerm::new(
461 interner,
462 self.def_id,
463 [self_ty.into()].iter().chain(self.args.iter()),
464 ),
465 term: self.term,
466 }
467 }
468
469 pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
470 projection_predicate.projection_term.args.type_at(0);
472
473 Self {
474 def_id: projection_predicate.projection_term.def_id,
475 args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
476 term: projection_predicate.term,
477 use_existential_projection_new_instead: (),
478 }
479 }
480}
481
482impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
483 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
484 self.map_bound(|p| p.with_self_ty(cx, self_ty))
485 }
486
487 pub fn item_def_id(&self) -> I::DefId {
488 self.skip_binder().def_id
489 }
490}
491
492#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
493#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
494pub enum AliasTermKind {
495 ProjectionTy,
498 InherentTy,
500 OpaqueTy,
503 FreeTy,
507
508 UnevaluatedConst,
510 ProjectionConst,
512 FreeConst,
514 InherentConst,
516}
517
518impl AliasTermKind {
519 pub fn descr(self) -> &'static str {
520 match self {
521 AliasTermKind::ProjectionTy => "associated type",
522 AliasTermKind::ProjectionConst => "associated const",
523 AliasTermKind::InherentTy => "inherent associated type",
524 AliasTermKind::InherentConst => "inherent associated const",
525 AliasTermKind::OpaqueTy => "opaque type",
526 AliasTermKind::FreeTy => "type alias",
527 AliasTermKind::FreeConst => "unevaluated constant",
528 AliasTermKind::UnevaluatedConst => "unevaluated constant",
529 }
530 }
531
532 pub fn is_type(self) -> bool {
533 match self {
534 AliasTermKind::ProjectionTy
535 | AliasTermKind::InherentTy
536 | AliasTermKind::OpaqueTy
537 | AliasTermKind::FreeTy => true,
538
539 AliasTermKind::UnevaluatedConst
540 | AliasTermKind::ProjectionConst
541 | AliasTermKind::InherentConst
542 | AliasTermKind::FreeConst => false,
543 }
544 }
545}
546
547impl From<ty::AliasTyKind> for AliasTermKind {
548 fn from(value: ty::AliasTyKind) -> Self {
549 match value {
550 ty::Projection => AliasTermKind::ProjectionTy,
551 ty::Opaque => AliasTermKind::OpaqueTy,
552 ty::Free => AliasTermKind::FreeTy,
553 ty::Inherent => AliasTermKind::InherentTy,
554 }
555 }
556}
557
558#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
564#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
565#[cfg_attr(
566 feature = "nightly",
567 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
568)]
569pub struct AliasTerm<I: Interner> {
570 pub args: I::GenericArgs,
581
582 pub def_id: I::DefId,
593
594 #[derive_where(skip(Debug))]
596 _use_alias_term_new_instead: (),
597}
598
599impl<I: Interner> Eq for AliasTerm<I> {}
600
601impl<I: Interner> AliasTerm<I> {
602 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
603 interner.debug_assert_args_compatible(def_id, args);
604 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
605 }
606
607 pub fn new(
608 interner: I,
609 def_id: I::DefId,
610 args: impl IntoIterator<Item: Into<I::GenericArg>>,
611 ) -> AliasTerm<I> {
612 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
613 Self::new_from_args(interner, def_id, args)
614 }
615
616 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
617 match self.kind(interner) {
618 AliasTermKind::ProjectionTy
619 | AliasTermKind::InherentTy
620 | AliasTermKind::OpaqueTy
621 | AliasTermKind::FreeTy => {}
622 AliasTermKind::InherentConst
623 | AliasTermKind::FreeConst
624 | AliasTermKind::UnevaluatedConst
625 | AliasTermKind::ProjectionConst => {
626 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
627 }
628 }
629 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
630 }
631
632 pub fn kind(self, interner: I) -> AliasTermKind {
633 interner.alias_term_kind(self)
634 }
635
636 pub fn to_term(self, interner: I) -> I::Term {
637 match self.kind(interner) {
638 AliasTermKind::ProjectionTy => Ty::new_alias(
639 interner,
640 ty::AliasTyKind::Projection,
641 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
642 )
643 .into(),
644 AliasTermKind::InherentTy => Ty::new_alias(
645 interner,
646 ty::AliasTyKind::Inherent,
647 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
648 )
649 .into(),
650 AliasTermKind::OpaqueTy => Ty::new_alias(
651 interner,
652 ty::AliasTyKind::Opaque,
653 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
654 )
655 .into(),
656 AliasTermKind::FreeTy => Ty::new_alias(
657 interner,
658 ty::AliasTyKind::Free,
659 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
660 )
661 .into(),
662 AliasTermKind::FreeConst
663 | AliasTermKind::InherentConst
664 | AliasTermKind::UnevaluatedConst
665 | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
666 interner,
667 ty::UnevaluatedConst::new(self.def_id.try_into().unwrap(), self.args),
668 )
669 .into(),
670 }
671 }
672}
673
674impl<I: Interner> AliasTerm<I> {
676 pub fn self_ty(self) -> I::Ty {
677 self.args.type_at(0)
678 }
679
680 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
681 AliasTerm::new(
682 interner,
683 self.def_id,
684 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
685 )
686 }
687
688 pub fn trait_def_id(self, interner: I) -> I::TraitId {
689 assert!(
690 matches!(
691 self.kind(interner),
692 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
693 ),
694 "expected a projection"
695 );
696 interner.parent(self.def_id).try_into().unwrap()
697 }
698
699 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
704 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
705 }
706
707 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
715 self.trait_ref_and_own_args(interner).0
716 }
717
718 pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
722 self.trait_ref_and_own_args(interner).1
723 }
724}
725
726impl<I: Interner> AliasTerm<I> {
728 pub fn rebase_inherent_args_onto_impl(
739 self,
740 impl_args: I::GenericArgs,
741 interner: I,
742 ) -> I::GenericArgs {
743 debug_assert!(matches!(
744 self.kind(interner),
745 AliasTermKind::InherentTy | AliasTermKind::InherentConst
746 ));
747 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
748 }
749}
750
751impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
752 fn from(ty: ty::AliasTy<I>) -> Self {
753 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
754 }
755}
756
757impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
758 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
759 AliasTerm { args: ct.args, def_id: ct.def.into(), _use_alias_term_new_instead: () }
760 }
761}
762
763#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
776#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
777#[cfg_attr(
778 feature = "nightly",
779 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
780)]
781pub struct ProjectionPredicate<I: Interner> {
782 pub projection_term: AliasTerm<I>,
783 pub term: I::Term,
784}
785
786impl<I: Interner> Eq for ProjectionPredicate<I> {}
787
788impl<I: Interner> ProjectionPredicate<I> {
789 pub fn self_ty(self) -> I::Ty {
790 self.projection_term.self_ty()
791 }
792
793 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
794 Self {
795 projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
796 ..self
797 }
798 }
799
800 pub fn trait_def_id(self, interner: I) -> I::TraitId {
801 self.projection_term.trait_def_id(interner)
802 }
803
804 pub fn def_id(self) -> I::DefId {
805 self.projection_term.def_id
806 }
807}
808
809impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
810 #[inline]
812 pub fn trait_def_id(&self, cx: I) -> I::TraitId {
813 self.skip_binder().projection_term.trait_def_id(cx)
814 }
815
816 pub fn term(&self) -> ty::Binder<I, I::Term> {
817 self.map_bound(|predicate| predicate.term)
818 }
819
820 pub fn item_def_id(&self) -> I::DefId {
825 self.skip_binder().projection_term.def_id
827 }
828}
829
830impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
831 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
832 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
833 }
834}
835
836#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
839#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
840#[cfg_attr(
841 feature = "nightly",
842 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
843)]
844pub struct NormalizesTo<I: Interner> {
845 pub alias: AliasTerm<I>,
846 pub term: I::Term,
847}
848
849impl<I: Interner> Eq for NormalizesTo<I> {}
850
851impl<I: Interner> NormalizesTo<I> {
852 pub fn self_ty(self) -> I::Ty {
853 self.alias.self_ty()
854 }
855
856 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
857 Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
858 }
859
860 pub fn trait_def_id(self, interner: I) -> I::TraitId {
861 self.alias.trait_def_id(interner)
862 }
863
864 pub fn def_id(self) -> I::DefId {
865 self.alias.def_id
866 }
867}
868
869impl<I: Interner> fmt::Debug for NormalizesTo<I> {
870 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
871 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
872 }
873}
874
875#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
876#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
877#[cfg_attr(
878 feature = "nightly",
879 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
880)]
881pub struct HostEffectPredicate<I: Interner> {
882 pub trait_ref: ty::TraitRef<I>,
883 pub constness: BoundConstness,
884}
885
886impl<I: Interner> Eq for HostEffectPredicate<I> {}
887
888impl<I: Interner> HostEffectPredicate<I> {
889 pub fn self_ty(self) -> I::Ty {
890 self.trait_ref.self_ty()
891 }
892
893 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
894 Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
895 }
896
897 pub fn def_id(self) -> I::TraitId {
898 self.trait_ref.def_id
899 }
900}
901
902impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
903 pub fn def_id(self) -> I::TraitId {
904 self.skip_binder().def_id()
906 }
907
908 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
909 self.map_bound(|trait_ref| trait_ref.self_ty())
910 }
911
912 #[inline]
913 pub fn constness(self) -> BoundConstness {
914 self.skip_binder().constness
915 }
916}
917
918#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
922#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
923#[cfg_attr(
924 feature = "nightly",
925 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
926)]
927pub struct SubtypePredicate<I: Interner> {
928 pub a_is_expected: bool,
929 pub a: I::Ty,
930 pub b: I::Ty,
931}
932
933impl<I: Interner> Eq for SubtypePredicate<I> {}
934
935#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
937#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
938#[cfg_attr(
939 feature = "nightly",
940 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
941)]
942pub struct CoercePredicate<I: Interner> {
943 pub a: I::Ty,
944 pub b: I::Ty,
945}
946
947impl<I: Interner> Eq for CoercePredicate<I> {}
948
949#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
950#[cfg_attr(
951 feature = "nightly",
952 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
953)]
954pub enum BoundConstness {
955 Const,
959 Maybe,
963}
964
965impl BoundConstness {
966 pub fn satisfies(self, goal: BoundConstness) -> bool {
967 match (self, goal) {
968 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
969 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
970 (BoundConstness::Maybe, BoundConstness::Const) => false,
971 }
972 }
973
974 pub fn as_str(self) -> &'static str {
975 match self {
976 Self::Const => "const",
977 Self::Maybe => "[const]",
978 }
979 }
980}
981
982impl fmt::Display for BoundConstness {
983 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984 match self {
985 Self::Const => f.write_str("const"),
986 Self::Maybe => f.write_str("[const]"),
987 }
988 }
989}