1use std::fmt;
2use std::hash::Hash;
3
4use derive_where::derive_where;
5#[cfg(feature = "nightly")]
6use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
7use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
8
9use crate::inherent::*;
10use crate::lift::Lift;
11use crate::upcast::{Upcast, UpcastFrom};
12use crate::visit::TypeVisitableExt as _;
13use crate::{self as ty, Interner};
14
15#[derive_where(Clone; I: Interner, A: Clone)]
17#[derive_where(Copy; I: Interner, A: Copy)]
18#[derive_where(Hash; I: Interner, A: Hash)]
19#[derive_where(PartialEq; I: Interner, A: PartialEq)]
20#[derive_where(Eq; I: Interner, A: Eq)]
21#[derive_where(Debug; I: Interner, A: fmt::Debug)]
22#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
23#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
24pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
25
26impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A>
29where
30 A: Lift<U>,
31 I::Region: Lift<U, Lifted = U::Region>,
32{
33 type Lifted = OutlivesPredicate<U, A::Lifted>;
34
35 fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
36 Some(OutlivesPredicate(self.0.lift_to_interner(cx)?, self.1.lift_to_interner(cx)?))
37 }
38}
39
40#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
52#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
53#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
54pub struct TraitRef<I: Interner> {
55 pub def_id: I::DefId,
56 pub args: I::GenericArgs,
57 _use_trait_ref_new_instead: (),
60}
61
62impl<I: Interner> TraitRef<I> {
63 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
64 interner.debug_assert_args_compatible(trait_def_id, args);
65 Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
66 }
67
68 pub fn new(
69 interner: I,
70 trait_def_id: I::DefId,
71 args: impl IntoIterator<Item: Into<I::GenericArg>>,
72 ) -> Self {
73 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
74 Self::new_from_args(interner, trait_def_id, args)
75 }
76
77 pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
78 let generics = interner.generics_of(trait_id);
79 TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
80 }
81
82 pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
85 TraitRef::new_from_args(
86 interner,
87 def_id,
88 I::GenericArgs::identity_for_item(interner, def_id),
89 )
90 }
91
92 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
93 TraitRef::new(
94 interner,
95 self.def_id,
96 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
97 )
98 }
99
100 #[inline]
101 pub fn self_ty(&self) -> I::Ty {
102 self.args.type_at(0)
103 }
104}
105
106impl<I: Interner> ty::Binder<I, TraitRef<I>> {
107 pub fn self_ty(&self) -> ty::Binder<I, I::Ty> {
108 self.map_bound_ref(|tr| tr.self_ty())
109 }
110
111 pub fn def_id(&self) -> I::DefId {
112 self.skip_binder().def_id
113 }
114
115 pub fn to_host_effect_clause(self, cx: I, constness: BoundConstness) -> I::Clause {
116 self.map_bound(|trait_ref| {
117 ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
118 })
119 .upcast(cx)
120 }
121}
122
123#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
124#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
125#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
126pub struct TraitPredicate<I: Interner> {
127 pub trait_ref: TraitRef<I>,
128
129 pub polarity: PredicatePolarity,
137}
138
139impl<I: Interner> TraitPredicate<I> {
140 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
141 Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity }
142 }
143
144 pub fn def_id(self) -> I::DefId {
145 self.trait_ref.def_id
146 }
147
148 pub fn self_ty(self) -> I::Ty {
149 self.trait_ref.self_ty()
150 }
151}
152
153impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
154 pub fn def_id(self) -> I::DefId {
155 self.skip_binder().def_id()
157 }
158
159 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
160 self.map_bound(|trait_ref| trait_ref.self_ty())
161 }
162
163 #[inline]
164 pub fn polarity(self) -> PredicatePolarity {
165 self.skip_binder().polarity
166 }
167}
168
169impl<I: Interner> UpcastFrom<I, TraitRef<I>> for TraitPredicate<I> {
170 fn upcast_from(from: TraitRef<I>, _tcx: I) -> Self {
171 TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
172 }
173}
174
175impl<I: Interner> fmt::Debug for TraitPredicate<I> {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
178 }
179}
180
181#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
182#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
183pub enum ImplPolarity {
184 Positive,
186 Negative,
188 Reservation,
193}
194
195impl fmt::Display for ImplPolarity {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 match self {
198 Self::Positive => f.write_str("positive"),
199 Self::Negative => f.write_str("negative"),
200 Self::Reservation => f.write_str("reservation"),
201 }
202 }
203}
204
205impl ImplPolarity {
206 pub fn as_str(self) -> &'static str {
208 match self {
209 Self::Positive => "",
210 Self::Negative => "!",
211 Self::Reservation => "",
212 }
213 }
214}
215
216#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
220#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
221pub enum PredicatePolarity {
222 Positive,
224 Negative,
226}
227
228impl PredicatePolarity {
229 pub fn flip(&self) -> PredicatePolarity {
231 match self {
232 PredicatePolarity::Positive => PredicatePolarity::Negative,
233 PredicatePolarity::Negative => PredicatePolarity::Positive,
234 }
235 }
236}
237
238impl fmt::Display for PredicatePolarity {
239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240 match self {
241 Self::Positive => f.write_str("positive"),
242 Self::Negative => f.write_str("negative"),
243 }
244 }
245}
246
247#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
248#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
249#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
250pub enum ExistentialPredicate<I: Interner> {
251 Trait(ExistentialTraitRef<I>),
253 Projection(ExistentialProjection<I>),
255 AutoTrait(I::DefId),
257}
258
259impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
260 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause {
264 match self.skip_binder() {
265 ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx),
266 ExistentialPredicate::Projection(p) => {
267 self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
268 }
269 ExistentialPredicate::AutoTrait(did) => {
270 let generics = cx.generics_of(did);
271 let trait_ref = if generics.count() == 1 {
272 ty::TraitRef::new(cx, did, [self_ty])
273 } else {
274 let err_args = GenericArgs::extend_with_error(cx, did, &[self_ty.into()]);
277 ty::TraitRef::new_from_args(cx, did, err_args)
278 };
279 self.rebind(trait_ref).upcast(cx)
280 }
281 }
282 }
283}
284
285#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
293#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
294#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
295pub struct ExistentialTraitRef<I: Interner> {
296 pub def_id: I::DefId,
297 pub args: I::GenericArgs,
298 _use_existential_trait_ref_new_instead: (),
301}
302
303impl<I: Interner> ExistentialTraitRef<I> {
304 pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
305 interner.debug_assert_existential_args_compatible(trait_def_id, args);
306 Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
307 }
308
309 pub fn new(
310 interner: I,
311 trait_def_id: I::DefId,
312 args: impl IntoIterator<Item: Into<I::GenericArg>>,
313 ) -> Self {
314 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
315 Self::new_from_args(interner, trait_def_id, args)
316 }
317
318 pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
319 trait_ref.args.type_at(0);
321
322 ExistentialTraitRef {
323 def_id: trait_ref.def_id,
324 args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
325 _use_existential_trait_ref_new_instead: (),
326 }
327 }
328
329 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
334 TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
338 }
339}
340
341impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
342 pub fn def_id(&self) -> I::DefId {
343 self.skip_binder().def_id
344 }
345
346 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
351 self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
352 }
353}
354
355#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
357#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
358#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
359pub struct ExistentialProjection<I: Interner> {
360 pub def_id: I::DefId,
361 pub args: I::GenericArgs,
362 pub term: I::Term,
363
364 use_existential_projection_new_instead: (),
367}
368
369impl<I: Interner> ExistentialProjection<I> {
370 pub fn new_from_args(
371 interner: I,
372 def_id: I::DefId,
373 args: I::GenericArgs,
374 term: I::Term,
375 ) -> ExistentialProjection<I> {
376 interner.debug_assert_existential_args_compatible(def_id, args);
377 Self { def_id, args, term, use_existential_projection_new_instead: () }
378 }
379
380 pub fn new(
381 interner: I,
382 def_id: I::DefId,
383 args: impl IntoIterator<Item: Into<I::GenericArg>>,
384 term: I::Term,
385 ) -> ExistentialProjection<I> {
386 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
387 Self::new_from_args(interner, def_id, args, term)
388 }
389
390 pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
395 let def_id = interner.parent(self.def_id);
396 let args_count = interner.generics_of(def_id).count() - 1;
397 let args = interner.mk_args(&self.args.as_slice()[..args_count]);
398 ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
399 }
400
401 pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
402 debug_assert!(!self_ty.has_escaping_bound_vars());
404
405 ProjectionPredicate {
406 projection_term: AliasTerm::new(
407 interner,
408 self.def_id,
409 [self_ty.into()].iter().chain(self.args.iter()),
410 ),
411 term: self.term,
412 }
413 }
414
415 pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
416 projection_predicate.projection_term.args.type_at(0);
418
419 Self {
420 def_id: projection_predicate.projection_term.def_id,
421 args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
422 term: projection_predicate.term,
423 use_existential_projection_new_instead: (),
424 }
425 }
426}
427
428impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
429 pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
430 self.map_bound(|p| p.with_self_ty(cx, self_ty))
431 }
432
433 pub fn item_def_id(&self) -> I::DefId {
434 self.skip_binder().def_id
435 }
436}
437
438#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
439#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
440pub enum AliasTermKind {
441 ProjectionTy,
444 InherentTy,
446 OpaqueTy,
449 WeakTy,
453 UnevaluatedConst,
455 ProjectionConst,
457}
458
459impl AliasTermKind {
460 pub fn descr(self) -> &'static str {
461 match self {
462 AliasTermKind::ProjectionTy => "associated type",
463 AliasTermKind::ProjectionConst => "associated const",
464 AliasTermKind::InherentTy => "inherent associated type",
465 AliasTermKind::OpaqueTy => "opaque type",
466 AliasTermKind::WeakTy => "type alias",
467 AliasTermKind::UnevaluatedConst => "unevaluated constant",
468 }
469 }
470}
471
472impl From<ty::AliasTyKind> for AliasTermKind {
473 fn from(value: ty::AliasTyKind) -> Self {
474 match value {
475 ty::Projection => AliasTermKind::ProjectionTy,
476 ty::Opaque => AliasTermKind::OpaqueTy,
477 ty::Weak => AliasTermKind::WeakTy,
478 ty::Inherent => AliasTermKind::InherentTy,
479 }
480 }
481}
482
483#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
489#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
490#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
491pub struct AliasTerm<I: Interner> {
492 pub args: I::GenericArgs,
503
504 pub def_id: I::DefId,
515
516 #[derive_where(skip(Debug))]
518 _use_alias_term_new_instead: (),
519}
520
521impl<I: Interner> AliasTerm<I> {
522 pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
523 interner.debug_assert_args_compatible(def_id, args);
524 AliasTerm { def_id, args, _use_alias_term_new_instead: () }
525 }
526
527 pub fn new(
528 interner: I,
529 def_id: I::DefId,
530 args: impl IntoIterator<Item: Into<I::GenericArg>>,
531 ) -> AliasTerm<I> {
532 let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
533 Self::new_from_args(interner, def_id, args)
534 }
535
536 pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
537 match self.kind(interner) {
538 AliasTermKind::ProjectionTy
539 | AliasTermKind::InherentTy
540 | AliasTermKind::OpaqueTy
541 | AliasTermKind::WeakTy => {}
542 AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
543 panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
544 }
545 }
546 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
547 }
548
549 pub fn kind(self, interner: I) -> AliasTermKind {
550 interner.alias_term_kind(self)
551 }
552
553 pub fn to_term(self, interner: I) -> I::Term {
554 match self.kind(interner) {
555 AliasTermKind::ProjectionTy => Ty::new_alias(
556 interner,
557 ty::AliasTyKind::Projection,
558 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
559 )
560 .into(),
561 AliasTermKind::InherentTy => Ty::new_alias(
562 interner,
563 ty::AliasTyKind::Inherent,
564 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
565 )
566 .into(),
567 AliasTermKind::OpaqueTy => Ty::new_alias(
568 interner,
569 ty::AliasTyKind::Opaque,
570 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
571 )
572 .into(),
573 AliasTermKind::WeakTy => Ty::new_alias(
574 interner,
575 ty::AliasTyKind::Weak,
576 ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
577 )
578 .into(),
579 AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
580 I::Const::new_unevaluated(
581 interner,
582 ty::UnevaluatedConst::new(self.def_id, self.args),
583 )
584 .into()
585 }
586 }
587 }
588}
589
590impl<I: Interner> AliasTerm<I> {
592 pub fn self_ty(self) -> I::Ty {
593 self.args.type_at(0)
594 }
595
596 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
597 AliasTerm::new(
598 interner,
599 self.def_id,
600 [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
601 )
602 }
603
604 pub fn trait_def_id(self, interner: I) -> I::DefId {
605 assert!(
606 matches!(
607 self.kind(interner),
608 AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
609 ),
610 "expected a projection"
611 );
612 interner.parent(self.def_id)
613 }
614
615 pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
620 interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
621 }
622
623 pub fn trait_ref(self, interner: I) -> TraitRef<I> {
631 self.trait_ref_and_own_args(interner).0
632 }
633}
634
635impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
636 fn from(ty: ty::AliasTy<I>) -> Self {
637 AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
638 }
639}
640
641impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
642 fn from(ct: ty::UnevaluatedConst<I>) -> Self {
643 AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
644 }
645}
646
647#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
660#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
661#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
662pub struct ProjectionPredicate<I: Interner> {
663 pub projection_term: AliasTerm<I>,
664 pub term: I::Term,
665}
666
667impl<I: Interner> ProjectionPredicate<I> {
668 pub fn self_ty(self) -> I::Ty {
669 self.projection_term.self_ty()
670 }
671
672 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
673 Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
674 }
675
676 pub fn trait_def_id(self, interner: I) -> I::DefId {
677 self.projection_term.trait_def_id(interner)
678 }
679
680 pub fn def_id(self) -> I::DefId {
681 self.projection_term.def_id
682 }
683}
684
685impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
686 #[inline]
688 pub fn trait_def_id(&self, cx: I) -> I::DefId {
689 self.skip_binder().projection_term.trait_def_id(cx)
690 }
691
692 pub fn term(&self) -> ty::Binder<I, I::Term> {
693 self.map_bound(|predicate| predicate.term)
694 }
695
696 pub fn item_def_id(&self) -> I::DefId {
701 self.skip_binder().projection_term.def_id
703 }
704}
705
706impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
707 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
708 write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
709 }
710}
711
712#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
715#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
716#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
717pub struct NormalizesTo<I: Interner> {
718 pub alias: AliasTerm<I>,
719 pub term: I::Term,
720}
721
722impl<I: Interner> NormalizesTo<I> {
723 pub fn self_ty(self) -> I::Ty {
724 self.alias.self_ty()
725 }
726
727 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
728 Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
729 }
730
731 pub fn trait_def_id(self, interner: I) -> I::DefId {
732 self.alias.trait_def_id(interner)
733 }
734
735 pub fn def_id(self) -> I::DefId {
736 self.alias.def_id
737 }
738}
739
740impl<I: Interner> fmt::Debug for NormalizesTo<I> {
741 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742 write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
743 }
744}
745
746#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
747#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
748#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
749pub struct HostEffectPredicate<I: Interner> {
750 pub trait_ref: ty::TraitRef<I>,
751 pub constness: BoundConstness,
752}
753
754impl<I: Interner> HostEffectPredicate<I> {
755 pub fn self_ty(self) -> I::Ty {
756 self.trait_ref.self_ty()
757 }
758
759 pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
760 Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
761 }
762
763 pub fn def_id(self) -> I::DefId {
764 self.trait_ref.def_id
765 }
766}
767
768impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
769 pub fn def_id(self) -> I::DefId {
770 self.skip_binder().def_id()
772 }
773
774 pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
775 self.map_bound(|trait_ref| trait_ref.self_ty())
776 }
777
778 #[inline]
779 pub fn constness(self) -> BoundConstness {
780 self.skip_binder().constness
781 }
782}
783
784#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
788#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
789#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
790pub struct SubtypePredicate<I: Interner> {
791 pub a_is_expected: bool,
792 pub a: I::Ty,
793 pub b: I::Ty,
794}
795
796#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
798#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
799#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
800pub struct CoercePredicate<I: Interner> {
801 pub a: I::Ty,
802 pub b: I::Ty,
803}
804
805#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
806#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
807pub enum BoundConstness {
808 Const,
812 Maybe,
816}
817
818impl BoundConstness {
819 pub fn satisfies(self, goal: BoundConstness) -> bool {
820 match (self, goal) {
821 (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
822 (BoundConstness::Maybe, BoundConstness::Maybe) => true,
823 (BoundConstness::Maybe, BoundConstness::Const) => false,
824 }
825 }
826
827 pub fn as_str(self) -> &'static str {
828 match self {
829 Self::Const => "const",
830 Self::Maybe => "~const",
831 }
832 }
833}
834
835impl fmt::Display for BoundConstness {
836 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
837 match self {
838 Self::Const => f.write_str("const"),
839 Self::Maybe => f.write_str("~const"),
840 }
841 }
842}