1use std::fmt;
2
3use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
6use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
7
8use crate::{self as ty, Interner};
9
10#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
13#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
14#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
15pub enum ClauseKind<I: Interner> {
16 Trait(ty::TraitPredicate<I>),
20
21 RegionOutlives(ty::OutlivesPredicate<I, I::Region>),
23
24 TypeOutlives(ty::OutlivesPredicate<I, I::Ty>),
26
27 Projection(ty::ProjectionPredicate<I>),
30
31 ConstArgHasType(I::Const, I::Ty),
34
35 WellFormed(I::GenericArg),
37
38 ConstEvaluatable(I::Const),
40
41 HostEffect(ty::HostEffectPredicate<I>),
46}
47
48#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
49#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
50#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
51pub enum PredicateKind<I: Interner> {
52 Clause(ClauseKind<I>),
54
55 DynCompatible(I::DefId),
57
58 Subtype(ty::SubtypePredicate<I>),
64
65 Coerce(ty::CoercePredicate<I>),
74
75 ConstEquate(I::Const, I::Const),
77
78 Ambiguous,
81
82 NormalizesTo(ty::NormalizesTo<I>),
91
92 AliasRelate(I::Term, I::Term, AliasRelationDirection),
97}
98
99#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
100#[cfg_attr(feature = "nightly", derive(HashStable_NoContext, Encodable, Decodable))]
101pub enum AliasRelationDirection {
102 Equate,
103 Subtype,
104}
105
106impl std::fmt::Display for AliasRelationDirection {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 match self {
109 AliasRelationDirection::Equate => write!(f, "=="),
110 AliasRelationDirection::Subtype => write!(f, "<:"),
111 }
112 }
113}
114
115impl<I: Interner> fmt::Debug for ClauseKind<I> {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 match self {
118 ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
119 ClauseKind::HostEffect(data) => data.fmt(f),
120 ClauseKind::Trait(a) => a.fmt(f),
121 ClauseKind::RegionOutlives(pair) => pair.fmt(f),
122 ClauseKind::TypeOutlives(pair) => pair.fmt(f),
123 ClauseKind::Projection(pair) => pair.fmt(f),
124 ClauseKind::WellFormed(data) => write!(f, "WellFormed({data:?})"),
125 ClauseKind::ConstEvaluatable(ct) => {
126 write!(f, "ConstEvaluatable({ct:?})")
127 }
128 }
129 }
130}
131
132impl<I: Interner> fmt::Debug for PredicateKind<I> {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 match self {
135 PredicateKind::Clause(a) => a.fmt(f),
136 PredicateKind::Subtype(pair) => pair.fmt(f),
137 PredicateKind::Coerce(pair) => pair.fmt(f),
138 PredicateKind::DynCompatible(trait_def_id) => {
139 write!(f, "DynCompatible({trait_def_id:?})")
140 }
141 PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
142 PredicateKind::Ambiguous => write!(f, "Ambiguous"),
143 PredicateKind::NormalizesTo(p) => p.fmt(f),
144 PredicateKind::AliasRelate(t1, t2, dir) => {
145 write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
146 }
147 }
148 }
149}