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, Debug; 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 FreeTy,
477
478 UnevaluatedConst,
480 ProjectionConst,
482 FreeConst,
484 InherentConst,
486}
487
488impl AliasTermKind {
489 pub fn descr(self) -> &'static str {
490 match self {
491 AliasTermKind::ProjectionTy => "associated type",
492 AliasTermKind::ProjectionConst => "associated const",
493 AliasTermKind::InherentTy => "inherent associated type",
494 AliasTermKind::InherentConst => "inherent associated const",
495 AliasTermKind::OpaqueTy => "opaque type",
496 AliasTermKind::FreeTy => "type alias",
497 AliasTermKind::FreeConst => "unevaluated constant",
498 AliasTermKind::UnevaluatedConst => "unevaluated constant",
499 }
500 }
501
502 pub fn is_type(self) -> bool {
503 match self {
504 AliasTermKind::ProjectionTy
505 | AliasTermKind::InherentTy
506 | AliasTermKind::OpaqueTy
507 | AliasTermKind::FreeTy => true,
508
509 AliasTermKind::UnevaluatedConst
510 | AliasTermKind::ProjectionConst
511 | AliasTermKind::InherentConst
512 | AliasTermKind::FreeConst => false,
513 }
514 }
515}
516
517impl From<ty::AliasTyKind> for AliasTermKind {
518 fn from(value: ty::AliasTyKind) -> Self {
519 match value {
520 ty::Projection => AliasTermKind::ProjectionTy,
521 ty::Opaque => AliasTermKind::OpaqueTy,
522 ty::Free => AliasTermKind::FreeTy,
523 ty::Inherent => AliasTermKind::InherentTy,
524 }
525 }
526}
527
528#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
534#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
535#[cfg_attr(
536 feature = "nightly",
537 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
538)]
539pub struct AliasTerm<I: Interner> {
540 pub args: I::GenericArgs,
551
552 pub def_id: I::DefId,
563
564 #[derive_where(skip(Debug))]
566 _use_alias_term_new_instead: (),
567}
568
569impl<I: Interner> AliasTerm<I> {
570 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
571 interner.debug_assert_args_compatible(def_id, args);
572 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
573 }
574
575 pub fn new(
576 interner: I,
577 def_id: I::DefId,
578 args: impl IntoIterator<Item: Into<I::GenericArg>>,
579 ) -> AliasTerm<I> {
580 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
581 Self::new_from_args(interner, def_id, args)
582 }
583
584 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
585 match self.kind(interner) {
586 AliasTermKind::ProjectionTy
587 | AliasTermKind::InherentTy
588 | AliasTermKind::OpaqueTy
589 | AliasTermKind::FreeTy => {}
590 AliasTermKind::InherentConst
591 | AliasTermKind::FreeConst
592 | AliasTermKind::UnevaluatedConst
593 | AliasTermKind::ProjectionConst => {
594 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
595 }
596 }
597 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
598 }
599
600 pub fn kind(self, interner: I) -> AliasTermKind {
601 interner.alias_term_kind(self)
602 }
603
604 pub fn to_term(self, interner: I) -> I::Term {
605 match self.kind(interner) {
606 AliasTermKind::ProjectionTy => Ty::new_alias(
607 interner,
608 ty::AliasTyKind::Projection,
609 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
610 )
611 .into(),
612 AliasTermKind::InherentTy => Ty::new_alias(
613 interner,
614 ty::AliasTyKind::Inherent,
615 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
616 )
617 .into(),
618 AliasTermKind::OpaqueTy => Ty::new_alias(
619 interner,
620 ty::AliasTyKind::Opaque,
621 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
622 )
623 .into(),
624 AliasTermKind::FreeTy => Ty::new_alias(
625 interner,
626 ty::AliasTyKind::Free,
627 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
628 )
629 .into(),
630 AliasTermKind::FreeConst
631 | AliasTermKind::InherentConst
632 | AliasTermKind::UnevaluatedConst
633 | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
634 interner,
635 ty::UnevaluatedConst::new(self.def_id, self.args),
636 )
637 .into(),
638 }
639 }
640}
641
642impl<I: Interner> AliasTerm<I> {
644 pub fn self_ty(self) -> I::Ty {
645 self.args.type_at(0)
646 }
647
648 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
649 AliasTerm::new(
650 interner,
651 self.def_id,
652 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
653 )
654 }
655
656 pub fn trait_def_id(self, interner: I) -> I::DefId {
657 assert!(
658 matches!(
659 self.kind(interner),
660 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
661 ),
662 "expected a projection"
663 );
664 interner.parent(self.def_id)
665 }
666
667 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
672 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
673 }
674
675 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
683 self.trait_ref_and_own_args(interner).0
684 }
685}
686
687impl<I: Interner> AliasTerm<I> {
689 pub fn rebase_inherent_args_onto_impl(
700 self,
701 impl_args: I::GenericArgs,
702 interner: I,
703 ) -> I::GenericArgs {
704 debug_assert!(matches!(
705 self.kind(interner),
706 AliasTermKind::InherentTy | AliasTermKind::InherentConst
707 ));
708 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
709 }
710}
711
712impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
713 fn from(ty: ty::AliasTy<I>) -> Self {
714 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
715 }
716}
717
718impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
719 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
720 AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
721 }
722}
723
724#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
737#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
738#[cfg_attr(
739 feature = "nightly",
740 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
741)]
742pub struct ProjectionPredicate<I: Interner> {
743 pub projection_term: AliasTerm<I>,
744 pub term: I::Term,
745}
746
747impl<I: Interner> ProjectionPredicate<I> {
748 pub fn self_ty(self) -> I::Ty {
749 self.projection_term.self_ty()
750 }
751
752 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
753 Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
754 }
755
756 pub fn trait_def_id(self, interner: I) -> I::DefId {
757 self.projection_term.trait_def_id(interner)
758 }
759
760 pub fn def_id(self) -> I::DefId {
761 self.projection_term.def_id
762 }
763}
764
765impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
766 #[inline]
768 pub fn trait_def_id(&self, cx: I) -> I::DefId {
769 self.skip_binder().projection_term.trait_def_id(cx)
770 }
771
772 pub fn term(&self) -> ty::Binder<I, I::Term> {
773 self.map_bound(|predicate| predicate.term)
774 }
775
776 pub fn item_def_id(&self) -> I::DefId {
781 self.skip_binder().projection_term.def_id
783 }
784}
785
786impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
789 }
790}
791
792#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
795#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
796#[cfg_attr(
797 feature = "nightly",
798 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
799)]
800pub struct NormalizesTo<I: Interner> {
801 pub alias: AliasTerm<I>,
802 pub term: I::Term,
803}
804
805impl<I: Interner> NormalizesTo<I> {
806 pub fn self_ty(self) -> I::Ty {
807 self.alias.self_ty()
808 }
809
810 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
811 Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
812 }
813
814 pub fn trait_def_id(self, interner: I) -> I::DefId {
815 self.alias.trait_def_id(interner)
816 }
817
818 pub fn def_id(self) -> I::DefId {
819 self.alias.def_id
820 }
821}
822
823impl<I: Interner> fmt::Debug for NormalizesTo<I> {
824 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
825 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
826 }
827}
828
829#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
830#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
831#[cfg_attr(
832 feature = "nightly",
833 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
834)]
835pub struct HostEffectPredicate<I: Interner> {
836 pub trait_ref: ty::TraitRef<I>,
837 pub constness: BoundConstness,
838}
839
840impl<I: Interner> HostEffectPredicate<I> {
841 pub fn self_ty(self) -> I::Ty {
842 self.trait_ref.self_ty()
843 }
844
845 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
846 Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
847 }
848
849 pub fn def_id(self) -> I::DefId {
850 self.trait_ref.def_id
851 }
852}
853
854impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
855 pub fn def_id(self) -> I::DefId {
856 self.skip_binder().def_id()
858 }
859
860 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
861 self.map_bound(|trait_ref| trait_ref.self_ty())
862 }
863
864 #[inline]
865 pub fn constness(self) -> BoundConstness {
866 self.skip_binder().constness
867 }
868}
869
870#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
874#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
875#[cfg_attr(
876 feature = "nightly",
877 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
878)]
879pub struct SubtypePredicate<I: Interner> {
880 pub a_is_expected: bool,
881 pub a: I::Ty,
882 pub b: I::Ty,
883}
884
885#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
887#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
888#[cfg_attr(
889 feature = "nightly",
890 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
891)]
892pub struct CoercePredicate<I: Interner> {
893 pub a: I::Ty,
894 pub b: I::Ty,
895}
896
897#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
898#[cfg_attr(
899 feature = "nightly",
900 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
901)]
902pub enum BoundConstness {
903 Const,
907 Maybe,
911}
912
913impl BoundConstness {
914 pub fn satisfies(self, goal: BoundConstness) -> bool {
915 match (self, goal) {
916 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
917 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
918 (BoundConstness::Maybe, BoundConstness::Const) => false,
919 }
920 }
921
922 pub fn as_str(self) -> &'static str {
923 match self {
924 Self::Const => "const",
925 Self::Maybe => "~const",
926 }
927 }
928}
929
930impl fmt::Display for BoundConstness {
931 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
932 match self {
933 Self::Const => f.write_str("const"),
934 Self::Maybe => f.write_str("~const"),
935 }
936 }
937}