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::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
10
11use crate::inherent::*;
12use crate::lift::Lift;
13use crate::upcast::{Upcast, UpcastFrom};
14use crate::visit::TypeVisitableExt as _;
15use crate::{self as ty, Interner};
16
17#[derive_where(Clone; I: Interner, A: Clone)]
19#[derive_where(Copy; I: Interner, A: Copy)]
20#[derive_where(Hash; I: Interner, A: Hash)]
21#[derive_where(PartialEq; I: Interner, A: PartialEq)]
22#[derive_where(Eq; I: Interner, A: Eq)]
23#[derive_where(Debug; I: Interner, A: fmt::Debug)]
24#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
25#[cfg_attr(
26 feature = "nightly",
27 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
28)]
29pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
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, Eq; I: Interner)]
57#[derive(TypeVisitable_Generic, 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::DefId,
64 pub args: I::GenericArgs,
65 _use_trait_ref_new_instead: (),
68}
69
70impl<I: Interner> TraitRef<I> {
71 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
72 interner.debug_assert_args_compatible(trait_def_id, args);
73 Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
74 }
75
76 pub fn new(
77 interner: I,
78 trait_def_id: I::DefId,
79 args: impl IntoIterator<Item: Into<I::GenericArg>>,
80 ) -> Self {
81 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
82 Self::new_from_args(interner, trait_def_id, args)
83 }
84
85 pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
86 let generics = interner.generics_of(trait_id);
87 TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
88 }
89
90 pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
93 TraitRef::new_from_args(
94 interner,
95 def_id,
96 I::GenericArgs::identity_for_item(interner, def_id),
97 )
98 }
99
100 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
101 TraitRef::new(
102 interner,
103 self.def_id,
104 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
105 )
106 }
107
108 #[inline]
109 pub fn self_ty(&self) -> I::Ty {
110 self.args.type_at(0)
111 }
112}
113
114impl<I: Interner> ty::Binder<I, TraitRef<I>> {
115 pub fn self_ty(&self) -> ty::Binder<I, I::Ty> {
116 self.map_bound_ref(|tr| tr.self_ty())
117 }
118
119 pub fn def_id(&self) -> I::DefId {
120 self.skip_binder().def_id
121 }
122
123 pub fn to_host_effect_clause(self, cx: I, constness: BoundConstness) -> I::Clause {
124 self.map_bound(|trait_ref| {
125 ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
126 })
127 .upcast(cx)
128 }
129}
130
131#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
132#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
133#[cfg_attr(
134 feature = "nightly",
135 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
136)]
137pub struct TraitPredicate<I: Interner> {
138 pub trait_ref: TraitRef<I>,
139
140 pub polarity: PredicatePolarity,
146}
147
148impl<I: Interner> TraitPredicate<I> {
149 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
150 Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity }
151 }
152
153 pub fn def_id(self) -> I::DefId {
154 self.trait_ref.def_id
155 }
156
157 pub fn self_ty(self) -> I::Ty {
158 self.trait_ref.self_ty()
159 }
160}
161
162impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
163 pub fn def_id(self) -> I::DefId {
164 self.skip_binder().def_id()
166 }
167
168 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
169 self.map_bound(|trait_ref| trait_ref.self_ty())
170 }
171
172 #[inline]
173 pub fn polarity(self) -> PredicatePolarity {
174 self.skip_binder().polarity
175 }
176}
177
178impl<I: Interner> UpcastFrom<I, TraitRef<I>> for TraitPredicate<I> {
179 fn upcast_from(from: TraitRef<I>, _tcx: I) -> Self {
180 TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
181 }
182}
183
184impl<I: Interner> fmt::Debug for TraitPredicate<I> {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
187 }
188}
189
190#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
191#[cfg_attr(
192 feature = "nightly",
193 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
194)]
195pub enum ImplPolarity {
196 Positive,
198 Negative,
200 Reservation,
205}
206
207impl fmt::Display for ImplPolarity {
208 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209 match self {
210 Self::Positive => f.write_str("positive"),
211 Self::Negative => f.write_str("negative"),
212 Self::Reservation => f.write_str("reservation"),
213 }
214 }
215}
216
217impl ImplPolarity {
218 pub fn as_str(self) -> &'static str {
220 match self {
221 Self::Positive => "",
222 Self::Negative => "!",
223 Self::Reservation => "",
224 }
225 }
226}
227
228#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
232#[cfg_attr(
233 feature = "nightly",
234 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
235)]
236pub enum PredicatePolarity {
237 Positive,
239 Negative,
241}
242
243impl PredicatePolarity {
244 pub fn flip(&self) -> PredicatePolarity {
246 match self {
247 PredicatePolarity::Positive => PredicatePolarity::Negative,
248 PredicatePolarity::Negative => PredicatePolarity::Positive,
249 }
250 }
251}
252
253impl fmt::Display for PredicatePolarity {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 match self {
256 Self::Positive => f.write_str("positive"),
257 Self::Negative => f.write_str("negative"),
258 }
259 }
260}
261
262#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
263#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
264#[cfg_attr(
265 feature = "nightly",
266 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
267)]
268pub enum ExistentialPredicate<I: Interner> {
269 Trait(ExistentialTraitRef<I>),
271 Projection(ExistentialProjection<I>),
273 AutoTrait(I::DefId),
275}
276
277impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
278 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause {
282 match self.skip_binder() {
283 ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx),
284 ExistentialPredicate::Projection(p) => {
285 self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
286 }
287 ExistentialPredicate::AutoTrait(did) => {
288 let generics = cx.generics_of(did);
289 let trait_ref = if generics.count() == 1 {
290 ty::TraitRef::new(cx, did, [self_ty])
291 } else {
292 let err_args = GenericArgs::extend_with_error(cx, did, &[self_ty.into()]);
295 ty::TraitRef::new_from_args(cx, did, err_args)
296 };
297 self.rebind(trait_ref).upcast(cx)
298 }
299 }
300 }
301}
302
303#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
311#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
312#[cfg_attr(
313 feature = "nightly",
314 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
315)]
316pub struct ExistentialTraitRef<I: Interner> {
317 pub def_id: I::DefId,
318 pub args: I::GenericArgs,
319 _use_existential_trait_ref_new_instead: (),
322}
323
324impl<I: Interner> ExistentialTraitRef<I> {
325 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
326 interner.debug_assert_existential_args_compatible(trait_def_id, args);
327 Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
328 }
329
330 pub fn new(
331 interner: I,
332 trait_def_id: I::DefId,
333 args: impl IntoIterator<Item: Into<I::GenericArg>>,
334 ) -> Self {
335 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
336 Self::new_from_args(interner, trait_def_id, args)
337 }
338
339 pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
340 trait_ref.args.type_at(0);
342
343 ExistentialTraitRef {
344 def_id: trait_ref.def_id,
345 args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
346 _use_existential_trait_ref_new_instead: (),
347 }
348 }
349
350 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
355 TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
359 }
360}
361
362impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
363 pub fn def_id(&self) -> I::DefId {
364 self.skip_binder().def_id
365 }
366
367 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
372 self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
373 }
374}
375
376#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
378#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
379#[cfg_attr(
380 feature = "nightly",
381 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
382)]
383pub struct ExistentialProjection<I: Interner> {
384 pub def_id: I::DefId,
385 pub args: I::GenericArgs,
386 pub term: I::Term,
387
388 use_existential_projection_new_instead: (),
391}
392
393impl<I: Interner> ExistentialProjection<I> {
394 pub fn new_from_args(
395 interner: I,
396 def_id: I::DefId,
397 args: I::GenericArgs,
398 term: I::Term,
399 ) -> ExistentialProjection<I> {
400 interner.debug_assert_existential_args_compatible(def_id, args);
401 Self { def_id, args, term, use_existential_projection_new_instead: () }
402 }
403
404 pub fn new(
405 interner: I,
406 def_id: I::DefId,
407 args: impl IntoIterator<Item: Into<I::GenericArg>>,
408 term: I::Term,
409 ) -> ExistentialProjection<I> {
410 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
411 Self::new_from_args(interner, def_id, args, term)
412 }
413
414 pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
419 let def_id = interner.parent(self.def_id);
420 let args_count = interner.generics_of(def_id).count() - 1;
421 let args = interner.mk_args(&self.args.as_slice()[..args_count]);
422 ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
423 }
424
425 pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
426 debug_assert!(!self_ty.has_escaping_bound_vars());
428
429 ProjectionPredicate {
430 projection_term: AliasTerm::new(
431 interner,
432 self.def_id,
433 [self_ty.into()].iter().chain(self.args.iter()),
434 ),
435 term: self.term,
436 }
437 }
438
439 pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
440 projection_predicate.projection_term.args.type_at(0);
442
443 Self {
444 def_id: projection_predicate.projection_term.def_id,
445 args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
446 term: projection_predicate.term,
447 use_existential_projection_new_instead: (),
448 }
449 }
450}
451
452impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
453 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
454 self.map_bound(|p| p.with_self_ty(cx, self_ty))
455 }
456
457 pub fn item_def_id(&self) -> I::DefId {
458 self.skip_binder().def_id
459 }
460}
461
462#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
463#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
464pub enum AliasTermKind {
465 ProjectionTy,
468 InherentTy,
470 OpaqueTy,
473 WeakTy,
477 UnevaluatedConst,
479 ProjectionConst,
481}
482
483impl AliasTermKind {
484 pub fn descr(self) -> &'static str {
485 match self {
486 AliasTermKind::ProjectionTy => "associated type",
487 AliasTermKind::ProjectionConst => "associated const",
488 AliasTermKind::InherentTy => "inherent associated type",
489 AliasTermKind::OpaqueTy => "opaque type",
490 AliasTermKind::WeakTy => "type alias",
491 AliasTermKind::UnevaluatedConst => "unevaluated constant",
492 }
493 }
494}
495
496impl From<ty::AliasTyKind> for AliasTermKind {
497 fn from(value: ty::AliasTyKind) -> Self {
498 match value {
499 ty::Projection => AliasTermKind::ProjectionTy,
500 ty::Opaque => AliasTermKind::OpaqueTy,
501 ty::Weak => AliasTermKind::WeakTy,
502 ty::Inherent => AliasTermKind::InherentTy,
503 }
504 }
505}
506
507#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
513#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
514#[cfg_attr(
515 feature = "nightly",
516 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
517)]
518pub struct AliasTerm<I: Interner> {
519 pub args: I::GenericArgs,
530
531 pub def_id: I::DefId,
542
543 #[derive_where(skip(Debug))]
545 _use_alias_term_new_instead: (),
546}
547
548impl<I: Interner> AliasTerm<I> {
549 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
550 interner.debug_assert_args_compatible(def_id, args);
551 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
552 }
553
554 pub fn new(
555 interner: I,
556 def_id: I::DefId,
557 args: impl IntoIterator<Item: Into<I::GenericArg>>,
558 ) -> AliasTerm<I> {
559 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
560 Self::new_from_args(interner, def_id, args)
561 }
562
563 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
564 match self.kind(interner) {
565 AliasTermKind::ProjectionTy
566 | AliasTermKind::InherentTy
567 | AliasTermKind::OpaqueTy
568 | AliasTermKind::WeakTy => {}
569 AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
570 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
571 }
572 }
573 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
574 }
575
576 pub fn kind(self, interner: I) -> AliasTermKind {
577 interner.alias_term_kind(self)
578 }
579
580 pub fn to_term(self, interner: I) -> I::Term {
581 match self.kind(interner) {
582 AliasTermKind::ProjectionTy => Ty::new_alias(
583 interner,
584 ty::AliasTyKind::Projection,
585 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
586 )
587 .into(),
588 AliasTermKind::InherentTy => Ty::new_alias(
589 interner,
590 ty::AliasTyKind::Inherent,
591 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
592 )
593 .into(),
594 AliasTermKind::OpaqueTy => Ty::new_alias(
595 interner,
596 ty::AliasTyKind::Opaque,
597 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
598 )
599 .into(),
600 AliasTermKind::WeakTy => Ty::new_alias(
601 interner,
602 ty::AliasTyKind::Weak,
603 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
604 )
605 .into(),
606 AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
607 I::Const::new_unevaluated(
608 interner,
609 ty::UnevaluatedConst::new(self.def_id, self.args),
610 )
611 .into()
612 }
613 }
614 }
615}
616
617impl<I: Interner> AliasTerm<I> {
619 pub fn self_ty(self) -> I::Ty {
620 self.args.type_at(0)
621 }
622
623 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
624 AliasTerm::new(
625 interner,
626 self.def_id,
627 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
628 )
629 }
630
631 pub fn trait_def_id(self, interner: I) -> I::DefId {
632 assert!(
633 matches!(
634 self.kind(interner),
635 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
636 ),
637 "expected a projection"
638 );
639 interner.parent(self.def_id)
640 }
641
642 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
647 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
648 }
649
650 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
658 self.trait_ref_and_own_args(interner).0
659 }
660}
661
662impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
663 fn from(ty: ty::AliasTy<I>) -> Self {
664 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
665 }
666}
667
668impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
669 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
670 AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
671 }
672}
673
674#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
687#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
688#[cfg_attr(
689 feature = "nightly",
690 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
691)]
692pub struct ProjectionPredicate<I: Interner> {
693 pub projection_term: AliasTerm<I>,
694 pub term: I::Term,
695}
696
697impl<I: Interner> ProjectionPredicate<I> {
698 pub fn self_ty(self) -> I::Ty {
699 self.projection_term.self_ty()
700 }
701
702 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
703 Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
704 }
705
706 pub fn trait_def_id(self, interner: I) -> I::DefId {
707 self.projection_term.trait_def_id(interner)
708 }
709
710 pub fn def_id(self) -> I::DefId {
711 self.projection_term.def_id
712 }
713}
714
715impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
716 #[inline]
718 pub fn trait_def_id(&self, cx: I) -> I::DefId {
719 self.skip_binder().projection_term.trait_def_id(cx)
720 }
721
722 pub fn term(&self) -> ty::Binder<I, I::Term> {
723 self.map_bound(|predicate| predicate.term)
724 }
725
726 pub fn item_def_id(&self) -> I::DefId {
731 self.skip_binder().projection_term.def_id
733 }
734}
735
736impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
737 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
738 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
739 }
740}
741
742#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
745#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
746#[cfg_attr(
747 feature = "nightly",
748 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
749)]
750pub struct NormalizesTo<I: Interner> {
751 pub alias: AliasTerm<I>,
752 pub term: I::Term,
753}
754
755impl<I: Interner> NormalizesTo<I> {
756 pub fn self_ty(self) -> I::Ty {
757 self.alias.self_ty()
758 }
759
760 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
761 Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
762 }
763
764 pub fn trait_def_id(self, interner: I) -> I::DefId {
765 self.alias.trait_def_id(interner)
766 }
767
768 pub fn def_id(self) -> I::DefId {
769 self.alias.def_id
770 }
771}
772
773impl<I: Interner> fmt::Debug for NormalizesTo<I> {
774 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
775 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
776 }
777}
778
779#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
780#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
781#[cfg_attr(
782 feature = "nightly",
783 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
784)]
785pub struct HostEffectPredicate<I: Interner> {
786 pub trait_ref: ty::TraitRef<I>,
787 pub constness: BoundConstness,
788}
789
790impl<I: Interner> HostEffectPredicate<I> {
791 pub fn self_ty(self) -> I::Ty {
792 self.trait_ref.self_ty()
793 }
794
795 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
796 Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
797 }
798
799 pub fn def_id(self) -> I::DefId {
800 self.trait_ref.def_id
801 }
802}
803
804impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
805 pub fn def_id(self) -> I::DefId {
806 self.skip_binder().def_id()
808 }
809
810 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
811 self.map_bound(|trait_ref| trait_ref.self_ty())
812 }
813
814 #[inline]
815 pub fn constness(self) -> BoundConstness {
816 self.skip_binder().constness
817 }
818}
819
820#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
824#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
825#[cfg_attr(
826 feature = "nightly",
827 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
828)]
829pub struct SubtypePredicate<I: Interner> {
830 pub a_is_expected: bool,
831 pub a: I::Ty,
832 pub b: I::Ty,
833}
834
835#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
837#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
838#[cfg_attr(
839 feature = "nightly",
840 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
841)]
842pub struct CoercePredicate<I: Interner> {
843 pub a: I::Ty,
844 pub b: I::Ty,
845}
846
847#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
848#[cfg_attr(
849 feature = "nightly",
850 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
851)]
852pub enum BoundConstness {
853 Const,
857 Maybe,
861}
862
863impl BoundConstness {
864 pub fn satisfies(self, goal: BoundConstness) -> bool {
865 match (self, goal) {
866 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
867 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
868 (BoundConstness::Maybe, BoundConstness::Const) => false,
869 }
870 }
871
872 pub fn as_str(self) -> &'static str {
873 match self {
874 Self::Const => "const",
875 Self::Maybe => "~const",
876 }
877 }
878}
879
880impl fmt::Display for BoundConstness {
881 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
882 match self {
883 Self::Const => f.write_str("const"),
884 Self::Maybe => f.write_str("~const"),
885 }
886 }
887}