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::TraitId,
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::TraitId, args: I::GenericArgs) -> Self {
72 interner.debug_assert_args_compatible(trait_def_id.into(), 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::TraitId,
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::TraitId, args: I::GenericArgs) -> TraitRef<I> {
86 let generics = interner.generics_of(trait_id.into());
87 TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
88 }
89
90 pub fn identity(interner: I, def_id: I::TraitId) -> TraitRef<I> {
93 TraitRef::new_from_args(
94 interner,
95 def_id,
96 I::GenericArgs::identity_for_item(interner, def_id.into()),
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::TraitId {
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::TraitId {
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::TraitId {
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::TraitId),
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.into());
305 let trait_ref = if generics.count() == 1 {
306 ty::TraitRef::new(cx, did, [self_ty])
307 } else {
308 let err_args =
311 GenericArgs::extend_with_error(cx, did.into(), &[self_ty.into()]);
312 ty::TraitRef::new_from_args(cx, did, err_args)
313 };
314 self.rebind(trait_ref).upcast(cx)
315 }
316 }
317 }
318}
319
320#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
328#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
329#[cfg_attr(
330 feature = "nightly",
331 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
332)]
333pub struct ExistentialTraitRef<I: Interner> {
334 pub def_id: I::TraitId,
335 pub args: I::GenericArgs,
336 _use_existential_trait_ref_new_instead: (),
339}
340
341impl<I: Interner> Eq for ExistentialTraitRef<I> {}
342
343impl<I: Interner> ExistentialTraitRef<I> {
344 pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
345 interner.debug_assert_existential_args_compatible(trait_def_id.into(), args);
346 Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
347 }
348
349 pub fn new(
350 interner: I,
351 trait_def_id: I::TraitId,
352 args: impl IntoIterator<Item: Into<I::GenericArg>>,
353 ) -> Self {
354 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
355 Self::new_from_args(interner, trait_def_id, args)
356 }
357
358 pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
359 trait_ref.args.type_at(0);
361
362 ExistentialTraitRef {
363 def_id: trait_ref.def_id,
364 args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
365 _use_existential_trait_ref_new_instead: (),
366 }
367 }
368
369 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
374 TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
378 }
379}
380
381impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
382 pub fn def_id(&self) -> I::TraitId {
383 self.skip_binder().def_id
384 }
385
386 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
391 self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
392 }
393}
394
395#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
397#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
398#[cfg_attr(
399 feature = "nightly",
400 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
401)]
402pub struct ExistentialProjection<I: Interner> {
403 pub def_id: I::DefId,
404 pub args: I::GenericArgs,
405 pub term: I::Term,
406
407 use_existential_projection_new_instead: (),
410}
411
412impl<I: Interner> Eq for ExistentialProjection<I> {}
413
414impl<I: Interner> ExistentialProjection<I> {
415 pub fn new_from_args(
416 interner: I,
417 def_id: I::DefId,
418 args: I::GenericArgs,
419 term: I::Term,
420 ) -> ExistentialProjection<I> {
421 interner.debug_assert_existential_args_compatible(def_id, args);
422 Self { def_id, args, term, use_existential_projection_new_instead: () }
423 }
424
425 pub fn new(
426 interner: I,
427 def_id: I::DefId,
428 args: impl IntoIterator<Item: Into<I::GenericArg>>,
429 term: I::Term,
430 ) -> ExistentialProjection<I> {
431 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
432 Self::new_from_args(interner, def_id, args, term)
433 }
434
435 pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
440 let def_id = interner.parent(self.def_id);
441 let args_count = interner.generics_of(def_id).count() - 1;
442 let args = interner.mk_args(&self.args.as_slice()[..args_count]);
443 ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args)
444 }
445
446 pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
447 debug_assert!(!self_ty.has_escaping_bound_vars());
449
450 ProjectionPredicate {
451 projection_term: AliasTerm::new(
452 interner,
453 self.def_id,
454 [self_ty.into()].iter().chain(self.args.iter()),
455 ),
456 term: self.term,
457 }
458 }
459
460 pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
461 projection_predicate.projection_term.args.type_at(0);
463
464 Self {
465 def_id: projection_predicate.projection_term.def_id,
466 args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
467 term: projection_predicate.term,
468 use_existential_projection_new_instead: (),
469 }
470 }
471}
472
473impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
474 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
475 self.map_bound(|p| p.with_self_ty(cx, self_ty))
476 }
477
478 pub fn item_def_id(&self) -> I::DefId {
479 self.skip_binder().def_id
480 }
481}
482
483#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
484#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
485pub enum AliasTermKind {
486 ProjectionTy,
489 InherentTy,
491 OpaqueTy,
494 FreeTy,
498
499 UnevaluatedConst,
501 ProjectionConst,
503 FreeConst,
505 InherentConst,
507}
508
509impl AliasTermKind {
510 pub fn descr(self) -> &'static str {
511 match self {
512 AliasTermKind::ProjectionTy => "associated type",
513 AliasTermKind::ProjectionConst => "associated const",
514 AliasTermKind::InherentTy => "inherent associated type",
515 AliasTermKind::InherentConst => "inherent associated const",
516 AliasTermKind::OpaqueTy => "opaque type",
517 AliasTermKind::FreeTy => "type alias",
518 AliasTermKind::FreeConst => "unevaluated constant",
519 AliasTermKind::UnevaluatedConst => "unevaluated constant",
520 }
521 }
522
523 pub fn is_type(self) -> bool {
524 match self {
525 AliasTermKind::ProjectionTy
526 | AliasTermKind::InherentTy
527 | AliasTermKind::OpaqueTy
528 | AliasTermKind::FreeTy => true,
529
530 AliasTermKind::UnevaluatedConst
531 | AliasTermKind::ProjectionConst
532 | AliasTermKind::InherentConst
533 | AliasTermKind::FreeConst => false,
534 }
535 }
536}
537
538impl From<ty::AliasTyKind> for AliasTermKind {
539 fn from(value: ty::AliasTyKind) -> Self {
540 match value {
541 ty::Projection => AliasTermKind::ProjectionTy,
542 ty::Opaque => AliasTermKind::OpaqueTy,
543 ty::Free => AliasTermKind::FreeTy,
544 ty::Inherent => AliasTermKind::InherentTy,
545 }
546 }
547}
548
549#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
555#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
556#[cfg_attr(
557 feature = "nightly",
558 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
559)]
560pub struct AliasTerm<I: Interner> {
561 pub args: I::GenericArgs,
572
573 pub def_id: I::DefId,
584
585 #[derive_where(skip(Debug))]
587 _use_alias_term_new_instead: (),
588}
589
590impl<I: Interner> Eq for AliasTerm<I> {}
591
592impl<I: Interner> AliasTerm<I> {
593 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
594 interner.debug_assert_args_compatible(def_id, args);
595 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
596 }
597
598 pub fn new(
599 interner: I,
600 def_id: I::DefId,
601 args: impl IntoIterator<Item: Into<I::GenericArg>>,
602 ) -> AliasTerm<I> {
603 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
604 Self::new_from_args(interner, def_id, args)
605 }
606
607 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
608 match self.kind(interner) {
609 AliasTermKind::ProjectionTy
610 | AliasTermKind::InherentTy
611 | AliasTermKind::OpaqueTy
612 | AliasTermKind::FreeTy => {}
613 AliasTermKind::InherentConst
614 | AliasTermKind::FreeConst
615 | AliasTermKind::UnevaluatedConst
616 | AliasTermKind::ProjectionConst => {
617 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
618 }
619 }
620 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
621 }
622
623 pub fn kind(self, interner: I) -> AliasTermKind {
624 interner.alias_term_kind(self)
625 }
626
627 pub fn to_term(self, interner: I) -> I::Term {
628 match self.kind(interner) {
629 AliasTermKind::ProjectionTy => Ty::new_alias(
630 interner,
631 ty::AliasTyKind::Projection,
632 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
633 )
634 .into(),
635 AliasTermKind::InherentTy => Ty::new_alias(
636 interner,
637 ty::AliasTyKind::Inherent,
638 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
639 )
640 .into(),
641 AliasTermKind::OpaqueTy => Ty::new_alias(
642 interner,
643 ty::AliasTyKind::Opaque,
644 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
645 )
646 .into(),
647 AliasTermKind::FreeTy => Ty::new_alias(
648 interner,
649 ty::AliasTyKind::Free,
650 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
651 )
652 .into(),
653 AliasTermKind::FreeConst
654 | AliasTermKind::InherentConst
655 | AliasTermKind::UnevaluatedConst
656 | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
657 interner,
658 ty::UnevaluatedConst::new(self.def_id, self.args),
659 )
660 .into(),
661 }
662 }
663}
664
665impl<I: Interner> AliasTerm<I> {
667 pub fn self_ty(self) -> I::Ty {
668 self.args.type_at(0)
669 }
670
671 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
672 AliasTerm::new(
673 interner,
674 self.def_id,
675 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
676 )
677 }
678
679 pub fn trait_def_id(self, interner: I) -> I::TraitId {
680 assert!(
681 matches!(
682 self.kind(interner),
683 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
684 ),
685 "expected a projection"
686 );
687 interner.parent(self.def_id).try_into().unwrap()
688 }
689
690 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
695 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
696 }
697
698 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
706 self.trait_ref_and_own_args(interner).0
707 }
708
709 pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
713 self.trait_ref_and_own_args(interner).1
714 }
715}
716
717impl<I: Interner> AliasTerm<I> {
719 pub fn rebase_inherent_args_onto_impl(
730 self,
731 impl_args: I::GenericArgs,
732 interner: I,
733 ) -> I::GenericArgs {
734 debug_assert!(matches!(
735 self.kind(interner),
736 AliasTermKind::InherentTy | AliasTermKind::InherentConst
737 ));
738 interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
739 }
740}
741
742impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
743 fn from(ty: ty::AliasTy<I>) -> Self {
744 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
745 }
746}
747
748impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
749 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
750 AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
751 }
752}
753
754#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
767#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
768#[cfg_attr(
769 feature = "nightly",
770 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
771)]
772pub struct ProjectionPredicate<I: Interner> {
773 pub projection_term: AliasTerm<I>,
774 pub term: I::Term,
775}
776
777impl<I: Interner> Eq for ProjectionPredicate<I> {}
778
779impl<I: Interner> ProjectionPredicate<I> {
780 pub fn self_ty(self) -> I::Ty {
781 self.projection_term.self_ty()
782 }
783
784 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
785 Self {
786 projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
787 ..self
788 }
789 }
790
791 pub fn trait_def_id(self, interner: I) -> I::TraitId {
792 self.projection_term.trait_def_id(interner)
793 }
794
795 pub fn def_id(self) -> I::DefId {
796 self.projection_term.def_id
797 }
798}
799
800impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
801 #[inline]
803 pub fn trait_def_id(&self, cx: I) -> I::TraitId {
804 self.skip_binder().projection_term.trait_def_id(cx)
805 }
806
807 pub fn term(&self) -> ty::Binder<I, I::Term> {
808 self.map_bound(|predicate| predicate.term)
809 }
810
811 pub fn item_def_id(&self) -> I::DefId {
816 self.skip_binder().projection_term.def_id
818 }
819}
820
821impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
822 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
823 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
824 }
825}
826
827#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
830#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
831#[cfg_attr(
832 feature = "nightly",
833 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
834)]
835pub struct NormalizesTo<I: Interner> {
836 pub alias: AliasTerm<I>,
837 pub term: I::Term,
838}
839
840impl<I: Interner> Eq for NormalizesTo<I> {}
841
842impl<I: Interner> NormalizesTo<I> {
843 pub fn self_ty(self) -> I::Ty {
844 self.alias.self_ty()
845 }
846
847 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
848 Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
849 }
850
851 pub fn trait_def_id(self, interner: I) -> I::TraitId {
852 self.alias.trait_def_id(interner)
853 }
854
855 pub fn def_id(self) -> I::DefId {
856 self.alias.def_id
857 }
858}
859
860impl<I: Interner> fmt::Debug for NormalizesTo<I> {
861 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
862 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
863 }
864}
865
866#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
867#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
868#[cfg_attr(
869 feature = "nightly",
870 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
871)]
872pub struct HostEffectPredicate<I: Interner> {
873 pub trait_ref: ty::TraitRef<I>,
874 pub constness: BoundConstness,
875}
876
877impl<I: Interner> Eq for HostEffectPredicate<I> {}
878
879impl<I: Interner> HostEffectPredicate<I> {
880 pub fn self_ty(self) -> I::Ty {
881 self.trait_ref.self_ty()
882 }
883
884 pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
885 Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
886 }
887
888 pub fn def_id(self) -> I::TraitId {
889 self.trait_ref.def_id
890 }
891}
892
893impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
894 pub fn def_id(self) -> I::TraitId {
895 self.skip_binder().def_id()
897 }
898
899 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
900 self.map_bound(|trait_ref| trait_ref.self_ty())
901 }
902
903 #[inline]
904 pub fn constness(self) -> BoundConstness {
905 self.skip_binder().constness
906 }
907}
908
909#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
913#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
914#[cfg_attr(
915 feature = "nightly",
916 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
917)]
918pub struct SubtypePredicate<I: Interner> {
919 pub a_is_expected: bool,
920 pub a: I::Ty,
921 pub b: I::Ty,
922}
923
924impl<I: Interner> Eq for SubtypePredicate<I> {}
925
926#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
928#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
929#[cfg_attr(
930 feature = "nightly",
931 derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
932)]
933pub struct CoercePredicate<I: Interner> {
934 pub a: I::Ty,
935 pub b: I::Ty,
936}
937
938impl<I: Interner> Eq for CoercePredicate<I> {}
939
940#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
941#[cfg_attr(
942 feature = "nightly",
943 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
944)]
945pub enum BoundConstness {
946 Const,
950 Maybe,
954}
955
956impl BoundConstness {
957 pub fn satisfies(self, goal: BoundConstness) -> bool {
958 match (self, goal) {
959 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
960 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
961 (BoundConstness::Maybe, BoundConstness::Const) => false,
962 }
963 }
964
965 pub fn as_str(self) -> &'static str {
966 match self {
967 Self::Const => "const",
968 Self::Maybe => "[const]",
969 }
970 }
971}
972
973impl fmt::Display for BoundConstness {
974 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
975 match self {
976 Self::Const => f.write_str("const"),
977 Self::Maybe => f.write_str("[const]"),
978 }
979 }
980}