1use std::fmt;
2
3use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
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(
15 feature = "nightly",
16 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
17)]
18pub enum ClauseKind<I: Interner> {
19 Trait(ty::TraitPredicate<I>),
23
24 RegionOutlives(ty::OutlivesPredicate<I, I::Region>),
26
27 TypeOutlives(ty::OutlivesPredicate<I, I::Ty>),
29
30 Projection(ty::ProjectionPredicate<I>),
33
34 ConstArgHasType(I::Const, I::Ty),
37
38 WellFormed(I::GenericArg),
40
41 ConstEvaluatable(I::Const),
43
44 HostEffect(ty::HostEffectPredicate<I>),
49}
50
51#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
52#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
53#[cfg_attr(
54 feature = "nightly",
55 derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
56)]
57pub enum PredicateKind<I: Interner> {
58 Clause(ClauseKind<I>),
60
61 DynCompatible(I::DefId),
63
64 Subtype(ty::SubtypePredicate<I>),
70
71 Coerce(ty::CoercePredicate<I>),
80
81 ConstEquate(I::Const, I::Const),
83
84 Ambiguous,
87
88 NormalizesTo(ty::NormalizesTo<I>),
97
98 AliasRelate(I::Term, I::Term, AliasRelationDirection),
103}
104
105#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
106#[cfg_attr(
107 feature = "nightly",
108 derive(HashStable_NoContext, Encodable_NoContext, Decodable_NoContext)
109)]
110pub enum AliasRelationDirection {
111 Equate,
112 Subtype,
113}
114
115impl std::fmt::Display for AliasRelationDirection {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 match self {
118 AliasRelationDirection::Equate => write!(f, "=="),
119 AliasRelationDirection::Subtype => write!(f, "<:"),
120 }
121 }
122}
123
124impl<I: Interner> fmt::Debug for ClauseKind<I> {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 match self {
127 ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
128 ClauseKind::HostEffect(data) => data.fmt(f),
129 ClauseKind::Trait(a) => a.fmt(f),
130 ClauseKind::RegionOutlives(pair) => pair.fmt(f),
131 ClauseKind::TypeOutlives(pair) => pair.fmt(f),
132 ClauseKind::Projection(pair) => pair.fmt(f),
133 ClauseKind::WellFormed(data) => write!(f, "WellFormed({data:?})"),
134 ClauseKind::ConstEvaluatable(ct) => {
135 write!(f, "ConstEvaluatable({ct:?})")
136 }
137 }
138 }
139}
140
141impl<I: Interner> fmt::Debug for PredicateKind<I> {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 match self {
144 PredicateKind::Clause(a) => a.fmt(f),
145 PredicateKind::Subtype(pair) => pair.fmt(f),
146 PredicateKind::Coerce(pair) => pair.fmt(f),
147 PredicateKind::DynCompatible(trait_def_id) => {
148 write!(f, "DynCompatible({trait_def_id:?})")
149 }
150 PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
151 PredicateKind::Ambiguous => write!(f, "Ambiguous"),
152 PredicateKind::NormalizesTo(p) => p.fmt(f),
153 PredicateKind::AliasRelate(t1, t2, dir) => {
154 write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
155 }
156 }
157 }
158}