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, Hash, PartialEq, Debug; I: Interner, A)]
19#[derive_where(Copy; I: Interner, A: Copy)]
20#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
21#[cfg_attr(
22 feature = "nightly",
23 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
24)]
25pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
26
27impl<I: Interner, A: Eq> Eq for OutlivesPredicate<I, A> {}
28
29impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A>
32where
33 A: Lift<U>,
34 I::Region: Lift<U, Lifted = U::Region>,
35{
36 type Lifted = OutlivesPredicate<U, A::Lifted>;
37
38 fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
39 Some(OutlivesPredicate(self.0.lift_to_interner(cx)?, self.1.lift_to_interner(cx)?))
40 }
41}
42
43#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
55#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
56#[cfg_attr(
57 feature = "nightly",
58 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
59)]
60pub struct TraitRef<I: Interner> {
61 pub def_id: I::DefId,
62 pub args: I::GenericArgs,
63 _use_trait_ref_new_instead: (),
66}
67
68impl<I: Interner> Eq for TraitRef<I> {}
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_assoc(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_replaced_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; 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> Eq for TraitPredicate<I> {}
149
150impl<I: Interner> TraitPredicate<I> {
151 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
152 Self {
153 trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty),
154 polarity: self.polarity,
155 }
156 }
157
158 pub fn def_id(self) -> I::DefId {
159 self.trait_ref.def_id
160 }
161
162 pub fn self_ty(self) -> I::Ty {
163 self.trait_ref.self_ty()
164 }
165}
166
167impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
168 pub fn def_id(self) -> I::DefId {
169 self.skip_binder().def_id()
171 }
172
173 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
174 self.map_bound(|trait_ref| trait_ref.self_ty())
175 }
176
177 #[inline]
178 pub fn polarity(self) -> PredicatePolarity {
179 self.skip_binder().polarity
180 }
181}
182
183impl<I: Interner> UpcastFrom<I, TraitRef<I>> for TraitPredicate<I> {
184 fn upcast_from(from: TraitRef<I>, _tcx: I) -> Self {
185 TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
186 }
187}
188
189impl<I: Interner> UpcastFrom<I, ty::Binder<I, TraitRef<I>>> for ty::Binder<I, TraitPredicate<I>> {
190 fn upcast_from(from: ty::Binder<I, TraitRef<I>>, _tcx: I) -> Self {
191 from.map_bound(|trait_ref| TraitPredicate {
192 trait_ref,
193 polarity: PredicatePolarity::Positive,
194 })
195 }
196}
197
198impl<I: Interner> fmt::Debug for TraitPredicate<I> {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
201 }
202}
203
204#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
205#[cfg_attr(
206 feature = "nightly",
207 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
208)]
209pub enum ImplPolarity {
210 Positive,
212 Negative,
214 Reservation,
219}
220
221impl fmt::Display for ImplPolarity {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 match self {
224 Self::Positive => f.write_str("positive"),
225 Self::Negative => f.write_str("negative"),
226 Self::Reservation => f.write_str("reservation"),
227 }
228 }
229}
230
231impl ImplPolarity {
232 pub fn as_str(self) -> &'static str {
234 match self {
235 Self::Positive => "",
236 Self::Negative => "!",
237 Self::Reservation => "",
238 }
239 }
240}
241
242#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
246#[cfg_attr(
247 feature = "nightly",
248 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
249)]
250pub enum PredicatePolarity {
251 Positive,
253 Negative,
255}
256
257impl PredicatePolarity {
258 pub fn flip(&self) -> PredicatePolarity {
260 match self {
261 PredicatePolarity::Positive => PredicatePolarity::Negative,
262 PredicatePolarity::Negative => PredicatePolarity::Positive,
263 }
264 }
265}
266
267impl fmt::Display for PredicatePolarity {
268 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 match self {
270 Self::Positive => f.write_str("positive"),
271 Self::Negative => f.write_str("negative"),
272 }
273 }
274}
275
276#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
277#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
278#[cfg_attr(
279 feature = "nightly",
280 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
281)]
282pub enum ExistentialPredicate<I: Interner> {
283 Trait(ExistentialTraitRef<I>),
285 Projection(ExistentialProjection<I>),
287 AutoTrait(I::DefId),
289}
290
291impl<I: Interner> Eq for ExistentialPredicate<I> {}
292
293impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
294 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause {
298 match self.skip_binder() {
299 ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx),
300 ExistentialPredicate::Projection(p) => {
301 self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
302 }
303 ExistentialPredicate::AutoTrait(did) => {
304 let generics = cx.generics_of(did);
305 let trait_ref = if generics.count() == 1 {
306 ty::TraitRef::new(cx, did, [self_ty])
307 } else {
308 let err_args = GenericArgs::extend_with_error(cx, did, &[self_ty.into()]);
311 ty::TraitRef::new_from_args(cx, did, err_args)
312 };
313 self.rebind(trait_ref).upcast(cx)
314 }
315 }
316 }
317}
318
319#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
327#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
328#[cfg_attr(
329 feature = "nightly",
330 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
331)]
332pub struct ExistentialTraitRef<I: Interner> {
333 pub def_id: I::DefId,
334 pub args: I::GenericArgs,
335 _use_existential_trait_ref_new_instead: (),
338}
339
340impl<I: Interner> Eq for ExistentialTraitRef<I> {}
341
342impl<I: Interner> ExistentialTraitRef<I> {
343 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
344 interner.debug_assert_existential_args_compatible(trait_def_id, args);
345 Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
346 }
347
348 pub fn new(
349 interner: I,
350 trait_def_id: I::DefId,
351 args: impl IntoIterator<Item: Into<I::GenericArg>>,
352 ) -> Self {
353 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
354 Self::new_from_args(interner, trait_def_id, args)
355 }
356
357 pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
358 trait_ref.args.type_at(0);
360
361 ExistentialTraitRef {
362 def_id: trait_ref.def_id,
363 args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
364 _use_existential_trait_ref_new_instead: (),
365 }
366 }
367
368 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
373 TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
377 }
378}
379
380impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
381 pub fn def_id(&self) -> I::DefId {
382 self.skip_binder().def_id
383 }
384
385 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
390 self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
391 }
392}
393
394#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
396#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
397#[cfg_attr(
398 feature = "nightly",
399 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
400)]
401pub struct ExistentialProjection<I: Interner> {
402 pub def_id: I::DefId,
403 pub args: I::GenericArgs,
404 pub term: I::Term,
405
406 use_existential_projection_new_instead: (),
409}
410
411impl<I: Interner> Eq for ExistentialProjection<I> {}
412
413impl<I: Interner> ExistentialProjection<I> {
414 pub fn new_from_args(
415 interner: I,
416 def_id: I::DefId,
417 args: I::GenericArgs,
418 term: I::Term,
419 ) -> ExistentialProjection<I> {
420 interner.debug_assert_existential_args_compatible(def_id, args);
421 Self { def_id, args, term, use_existential_projection_new_instead: () }
422 }
423
424 pub fn new(
425 interner: I,
426 def_id: I::DefId,
427 args: impl IntoIterator<Item: Into<I::GenericArg>>,
428 term: I::Term,
429 ) -> ExistentialProjection<I> {
430 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
431 Self::new_from_args(interner, def_id, args, term)
432 }
433
434 pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
439 let def_id = interner.parent(self.def_id);
440 let args_count = interner.generics_of(def_id).count() - 1;
441 let args = interner.mk_args(&self.args.as_slice()[..args_count]);
442 ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
443 }
444
445 pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
446 debug_assert!(!self_ty.has_escaping_bound_vars());
448
449 ProjectionPredicate {
450 projection_term: AliasTerm::new(
451 interner,
452 self.def_id,
453 [self_ty.into()].iter().chain(self.args.iter()),
454 ),
455 term: self.term,
456 }
457 }
458
459 pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
460 projection_predicate.projection_term.args.type_at(0);
462
463 Self {
464 def_id: projection_predicate.projection_term.def_id,
465 args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
466 term: projection_predicate.term,
467 use_existential_projection_new_instead: (),
468 }
469 }
470}
471
472impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
473 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
474 self.map_bound(|p| p.with_self_ty(cx, self_ty))
475 }
476
477 pub fn item_def_id(&self) -> I::DefId {
478 self.skip_binder().def_id
479 }
480}
481
482#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
483#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
484pub enum AliasTermKind {
485 ProjectionTy,
488 InherentTy,
490 OpaqueTy,
493 FreeTy,
497
498 UnevaluatedConst,
500 ProjectionConst,
502 FreeConst,
504 InherentConst,
506}
507
508impl AliasTermKind {
509 pub fn descr(self) -> &'static str {
510 match self {
511 AliasTermKind::ProjectionTy => "associated type",
512 AliasTermKind::ProjectionConst => "associated const",
513 AliasTermKind::InherentTy => "inherent associated type",
514 AliasTermKind::InherentConst => "inherent associated const",
515 AliasTermKind::OpaqueTy => "opaque type",
516 AliasTermKind::FreeTy => "type alias",
517 AliasTermKind::FreeConst => "unevaluated constant",
518 AliasTermKind::UnevaluatedConst => "unevaluated constant",
519 }
520 }
521
522 pub fn is_type(self) -> bool {
523 match self {
524 AliasTermKind::ProjectionTy
525 | AliasTermKind::InherentTy
526 | AliasTermKind::OpaqueTy
527 | AliasTermKind::FreeTy => true,
528
529 AliasTermKind::UnevaluatedConst
530 | AliasTermKind::ProjectionConst
531 | AliasTermKind::InherentConst
532 | AliasTermKind::FreeConst => false,
533 }
534 }
535}
536
537impl From<ty::AliasTyKind> for AliasTermKind {
538 fn from(value: ty::AliasTyKind) -> Self {
539 match value {
540 ty::Projection => AliasTermKind::ProjectionTy,
541 ty::Opaque => AliasTermKind::OpaqueTy,
542 ty::Free => AliasTermKind::FreeTy,
543 ty::Inherent => AliasTermKind::InherentTy,
544 }
545 }
546}
547
548#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
554#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
555#[cfg_attr(
556 feature = "nightly",
557 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
558)]
559pub struct AliasTerm<I: Interner> {
560 pub args: I::GenericArgs,
571
572 pub def_id: I::DefId,
583
584 #[derive_where(skip(Debug))]
586 _use_alias_term_new_instead: (),
587}
588
589impl<I: Interner> Eq for AliasTerm<I> {}
590
591impl<I: Interner> AliasTerm<I> {
592 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
593 interner.debug_assert_args_compatible(def_id, args);
594 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
595 }
596
597 pub fn new(
598 interner: I,
599 def_id: I::DefId,
600 args: impl IntoIterator<Item: Into<I::GenericArg>>,
601 ) -> AliasTerm<I> {
602 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
603 Self::new_from_args(interner, def_id, args)
604 }
605
606 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
607 match self.kind(interner) {
608 AliasTermKind::ProjectionTy
609 | AliasTermKind::InherentTy
610 | AliasTermKind::OpaqueTy
611 | AliasTermKind::FreeTy => {}
612 AliasTermKind::InherentConst
613 | AliasTermKind::FreeConst
614 | AliasTermKind::UnevaluatedConst
615 | AliasTermKind::ProjectionConst => {
616 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
617 }
618 }
619 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
620 }
621
622 pub fn kind(self, interner: I) -> AliasTermKind {
623 interner.alias_term_kind(self)
624 }
625
626 pub fn to_term(self, interner: I) -> I::Term {
627 match self.kind(interner) {
628 AliasTermKind::ProjectionTy => Ty::new_alias(
629 interner,
630 ty::AliasTyKind::Projection,
631 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
632 )
633 .into(),
634 AliasTermKind::InherentTy => Ty::new_alias(
635 interner,
636 ty::AliasTyKind::Inherent,
637 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
638 )
639 .into(),
640 AliasTermKind::OpaqueTy => Ty::new_alias(
641 interner,
642 ty::AliasTyKind::Opaque,
643 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
644 )
645 .into(),
646 AliasTermKind::FreeTy => Ty::new_alias(
647 interner,
648 ty::AliasTyKind::Free,
649 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
650 )
651 .into(),
652 AliasTermKind::FreeConst
653 | AliasTermKind::InherentConst
654 | AliasTermKind::UnevaluatedConst
655 | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
656 interner,
657 ty::UnevaluatedConst::new(self.def_id, self.args),
658 )
659 .into(),
660 }
661 }
662}
663
664impl<I: Interner> AliasTerm<I> {
666 pub fn self_ty(self) -> I::Ty {
667 self.args.type_at(0)
668 }
669
670 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
671 AliasTerm::new(
672 interner,
673 self.def_id,
674 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
675 )
676 }
677
678 pub fn trait_def_id(self, interner: I) -> I::DefId {
679 assert!(
680 matches!(
681 self.kind(interner),
682 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
683 ),
684 "expected a projection"
685 );
686 interner.parent(self.def_id)
687 }
688
689 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
694 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
695 }
696
697 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
705 self.trait_ref_and_own_args(interner).0
706 }
707
708 pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
712 self.trait_ref_and_own_args(interner).1
713 }
714}
715
716impl<I: Interner> AliasTerm<I> {
718 pub fn rebase_inherent_args_onto_impl(
729 self,
730 impl_args: I::GenericArgs,
731 interner: I,
732 ) -> I::GenericArgs {
733 debug_assert!(matches!(
734 self.kind(interner),
735 AliasTermKind::InherentTy | AliasTermKind::InherentConst
736 ));
737 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
738 }
739}
740
741impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
742 fn from(ty: ty::AliasTy<I>) -> Self {
743 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
744 }
745}
746
747impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
748 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
749 AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
750 }
751}
752
753#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
766#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
767#[cfg_attr(
768 feature = "nightly",
769 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
770)]
771pub struct ProjectionPredicate<I: Interner> {
772 pub projection_term: AliasTerm<I>,
773 pub term: I::Term,
774}
775
776impl<I: Interner> Eq for ProjectionPredicate<I> {}
777
778impl<I: Interner> ProjectionPredicate<I> {
779 pub fn self_ty(self) -> I::Ty {
780 self.projection_term.self_ty()
781 }
782
783 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
784 Self {
785 projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
786 ..self
787 }
788 }
789
790 pub fn trait_def_id(self, interner: I) -> I::DefId {
791 self.projection_term.trait_def_id(interner)
792 }
793
794 pub fn def_id(self) -> I::DefId {
795 self.projection_term.def_id
796 }
797}
798
799impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
800 #[inline]
802 pub fn trait_def_id(&self, cx: I) -> I::DefId {
803 self.skip_binder().projection_term.trait_def_id(cx)
804 }
805
806 pub fn term(&self) -> ty::Binder<I, I::Term> {
807 self.map_bound(|predicate| predicate.term)
808 }
809
810 pub fn item_def_id(&self) -> I::DefId {
815 self.skip_binder().projection_term.def_id
817 }
818}
819
820impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
821 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
822 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
823 }
824}
825
826#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
829#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
830#[cfg_attr(
831 feature = "nightly",
832 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
833)]
834pub struct NormalizesTo<I: Interner> {
835 pub alias: AliasTerm<I>,
836 pub term: I::Term,
837}
838
839impl<I: Interner> Eq for NormalizesTo<I> {}
840
841impl<I: Interner> NormalizesTo<I> {
842 pub fn self_ty(self) -> I::Ty {
843 self.alias.self_ty()
844 }
845
846 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
847 Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
848 }
849
850 pub fn trait_def_id(self, interner: I) -> I::DefId {
851 self.alias.trait_def_id(interner)
852 }
853
854 pub fn def_id(self) -> I::DefId {
855 self.alias.def_id
856 }
857}
858
859impl<I: Interner> fmt::Debug for NormalizesTo<I> {
860 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
861 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
862 }
863}
864
865#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
866#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
867#[cfg_attr(
868 feature = "nightly",
869 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
870)]
871pub struct HostEffectPredicate<I: Interner> {
872 pub trait_ref: ty::TraitRef<I>,
873 pub constness: BoundConstness,
874}
875
876impl<I: Interner> Eq for HostEffectPredicate<I> {}
877
878impl<I: Interner> HostEffectPredicate<I> {
879 pub fn self_ty(self) -> I::Ty {
880 self.trait_ref.self_ty()
881 }
882
883 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
884 Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
885 }
886
887 pub fn def_id(self) -> I::DefId {
888 self.trait_ref.def_id
889 }
890}
891
892impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
893 pub fn def_id(self) -> I::DefId {
894 self.skip_binder().def_id()
896 }
897
898 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
899 self.map_bound(|trait_ref| trait_ref.self_ty())
900 }
901
902 #[inline]
903 pub fn constness(self) -> BoundConstness {
904 self.skip_binder().constness
905 }
906}
907
908#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
912#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
913#[cfg_attr(
914 feature = "nightly",
915 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
916)]
917pub struct SubtypePredicate<I: Interner> {
918 pub a_is_expected: bool,
919 pub a: I::Ty,
920 pub b: I::Ty,
921}
922
923impl<I: Interner> Eq for SubtypePredicate<I> {}
924
925#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
927#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
928#[cfg_attr(
929 feature = "nightly",
930 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
931)]
932pub struct CoercePredicate<I: Interner> {
933 pub a: I::Ty,
934 pub b: I::Ty,
935}
936
937impl<I: Interner> Eq for CoercePredicate<I> {}
938
939#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
940#[cfg_attr(
941 feature = "nightly",
942 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
943)]
944pub enum BoundConstness {
945 Const,
949 Maybe,
953}
954
955impl BoundConstness {
956 pub fn satisfies(self, goal: BoundConstness) -> bool {
957 match (self, goal) {
958 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
959 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
960 (BoundConstness::Maybe, BoundConstness::Const) => false,
961 }
962 }
963
964 pub fn as_str(self) -> &'static str {
965 match self {
966 Self::Const => "const",
967 Self::Maybe => "[const]",
968 }
969 }
970}
971
972impl fmt::Display for BoundConstness {
973 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974 match self {
975 Self::Const => f.write_str("const"),
976 Self::Maybe => f.write_str("[const]"),
977 }
978 }
979}