1use std::cmp::Ordering;
2
3use rustc_data_structures::intern::Interned;
4use rustc_hir::def_id::DefId;
5use rustc_macros::{StableHash, extension};
6use rustc_type_ir as ir;
7
8use crate::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, WithCachedTypeInfo};
9
10pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
11pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>;
12pub type AliasTermKind<'tcx> = ir::AliasTermKind<TyCtxt<'tcx>>;
13pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>;
14pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
15pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
16pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
17pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
18pub type HostEffectClause<'tcx> = ir::HostEffectClause<TyCtxt<'tcx>>;
19pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
20pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
21pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
22pub type CoercePredicate<'tcx> = ir::CoercePredicate<TyCtxt<'tcx>>;
23pub type SubtypePredicate<'tcx> = ir::SubtypePredicate<TyCtxt<'tcx>>;
24pub type OutlivesClause<'tcx, T> = ir::OutlivesClause<TyCtxt<'tcx>, T>;
25pub type RegionOutlivesClause<'tcx> = OutlivesClause<'tcx, ty::Region<'tcx>>;
26pub type TypeOutlivesClause<'tcx> = OutlivesClause<'tcx, Ty<'tcx>>;
27pub type ArgOutlivesClause<'tcx> = OutlivesClause<'tcx, ty::GenericArg<'tcx>>;
28pub type RegionEqPredicate<'tcx> = ir::RegionEqPredicate<TyCtxt<'tcx>>;
29pub type RegionConstraint<'tcx> = ir::RegionConstraint<TyCtxt<'tcx>>;
30pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
31pub type PolyRegionOutlivesClause<'tcx> = ty::Binder<'tcx, RegionOutlivesClause<'tcx>>;
32pub type PolyTypeOutlivesClause<'tcx> = ty::Binder<'tcx, TypeOutlivesClause<'tcx>>;
33pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
34pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
35pub type PolyProjectionPredicate<'tcx> = ty::Binder<'tcx, ProjectionPredicate<'tcx>>;
36
37#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Predicate<'tcx> {
#[inline]
fn clone(&self) -> Predicate<'tcx> {
let _:
::core::clone::AssertParamIsClone<Interned<'tcx,
WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for Predicate<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Predicate<'tcx> {
#[inline]
fn eq(&self, other: &Predicate<'tcx>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Predicate<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _:
::core::cmp::AssertParamIsEq<Interned<'tcx,
WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Predicate<'tcx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
Predicate<'tcx> {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Predicate(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
44#[rustc_pass_by_value]
45pub struct Predicate<'tcx>(
46 pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
47);
48
49impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {
50 fn as_clause(self) -> Option<ty::Clause<'tcx>> {
51 self.as_clause()
52 }
53}
54
55impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> {
56 type Kind = ty::Binder<'tcx, ty::PredicateKind<'tcx>>;
57
58 fn kind(self) -> Self::Kind {
59 self.kind()
60 }
61}
62
63impl<'tcx> rustc_type_ir::Flags for Predicate<'tcx> {
64 fn flags(&self) -> TypeFlags {
65 self.0.flags
66 }
67
68 fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
69 self.0.outer_exclusive_binder
70 }
71}
72
73impl<'tcx> Predicate<'tcx> {
74 #[inline]
76 pub fn kind(self) -> ty::Binder<'tcx, PredicateKind<'tcx>> {
77 self.0.internee
78 }
79
80 pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
84 let kind = self
85 .kind()
86 .map_bound(|kind| match kind {
87 PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
88 trait_ref,
89 polarity,
90 })) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
91 trait_ref,
92 polarity: polarity.flip(),
93 }))),
94
95 _ => None,
96 })
97 .transpose()?;
98
99 Some(tcx.mk_predicate(kind))
100 }
101
102 #[inline]
108 pub fn allow_normalization(self) -> bool {
109 rustc_type_ir::inherent::Predicate::allow_normalization(self)
110 }
111}
112
113impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> {
114 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
115 ty::tls::with(|tcx| {
116 let pred = tcx.short_string(tcx.lift(self), path);
117 rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred))
118 })
119 }
120}
121
122impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> {
123 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
124 ty::tls::with(|tcx| {
125 let clause = tcx.short_string(tcx.lift(self), path);
126 rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause))
127 })
128 }
129}
130
131#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Clause<'tcx> {
#[inline]
fn clone(&self) -> Clause<'tcx> {
let _:
::core::clone::AssertParamIsClone<Interned<'tcx,
WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for Clause<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Clause<'tcx> {
#[inline]
fn eq(&self, other: &Clause<'tcx>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Clause<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _:
::core::cmp::AssertParamIsEq<Interned<'tcx,
WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Clause<'tcx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
Clause<'tcx> {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Clause(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
135#[rustc_pass_by_value]
136pub struct Clause<'tcx>(
137 pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
138);
139
140impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
141 fn as_predicate(self) -> Predicate<'tcx> {
142 self.as_predicate()
143 }
144
145 fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
146 self.instantiate_supertrait(tcx, trait_ref)
147 }
148}
149
150impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
151 type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
152
153 fn kind(self) -> Self::Kind {
154 self.kind()
155 }
156}
157
158impl<'tcx> rustc_type_ir::Flags for Clause<'tcx> {
159 fn flags(&self) -> TypeFlags {
160 self.0.flags
161 }
162
163 fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
164 self.0.outer_exclusive_binder
165 }
166}
167
168impl<'tcx> Clause<'tcx> {
169 pub fn as_predicate(self) -> Predicate<'tcx> {
170 Predicate(self.0)
171 }
172
173 pub fn kind(self) -> ty::Binder<'tcx, ClauseKind<'tcx>> {
174 self.0.internee.map_bound(|kind| match kind {
175 PredicateKind::Clause(clause) => clause,
176 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
177 })
178 }
179
180 pub fn as_trait_clause(self) -> Option<ty::Binder<'tcx, TraitPredicate<'tcx>>> {
181 let clause = self.kind();
182 if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() {
183 Some(clause.rebind(trait_clause))
184 } else {
185 None
186 }
187 }
188
189 pub fn as_projection_clause(self) -> Option<ty::Binder<'tcx, ProjectionPredicate<'tcx>>> {
190 let clause = self.kind();
191 if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() {
192 Some(clause.rebind(projection_clause))
193 } else {
194 None
195 }
196 }
197
198 pub fn as_type_outlives_clause(self) -> Option<ty::Binder<'tcx, TypeOutlivesClause<'tcx>>> {
199 let clause = self.kind();
200 if let ty::ClauseKind::TypeOutlives(o) = clause.skip_binder() {
201 Some(clause.rebind(o))
202 } else {
203 None
204 }
205 }
206
207 pub fn as_region_outlives_clause(self) -> Option<ty::Binder<'tcx, RegionOutlivesClause<'tcx>>> {
208 let clause = self.kind();
209 if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() {
210 Some(clause.rebind(o))
211 } else {
212 None
213 }
214 }
215}
216
217impl<'tcx> rustc_type_ir::inherent::Clauses<TyCtxt<'tcx>> for ty::Clauses<'tcx> {}
218
219impl<'tcx> ExistentialPredicateStableCmpExt<'tcx> for
ExistentialPredicate<'tcx> {
#[doc =
" Compares via an ordering that will not change if modules are reordered or other changes are"]
#[doc =
" made to the tree. In particular, this ordering is preserved across incremental compilations."]
fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
match (*self, *other) {
(ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_))
=> Ordering::Equal,
(ExistentialPredicate::Projection(ref a),
ExistentialPredicate::Projection(ref b)) => {
tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
}
(ExistentialPredicate::AutoTrait(ref a),
ExistentialPredicate::AutoTrait(ref b)) => {
tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
}
(ExistentialPredicate::Trait(_), _) => Ordering::Less,
(ExistentialPredicate::Projection(_),
ExistentialPredicate::Trait(_)) => {
Ordering::Greater
}
(ExistentialPredicate::Projection(_), _) => Ordering::Less,
(ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
}
}
}#[extension(pub trait ExistentialPredicateStableCmpExt<'tcx>)]
220impl<'tcx> ExistentialPredicate<'tcx> {
221 fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
224 match (*self, *other) {
225 (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
226 (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => {
227 tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
228 }
229 (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => {
230 tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
231 }
232 (ExistentialPredicate::Trait(_), _) => Ordering::Less,
233 (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => {
234 Ordering::Greater
235 }
236 (ExistentialPredicate::Projection(_), _) => Ordering::Less,
237 (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
238 }
239 }
240}
241
242pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
243
244impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
245 for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
246{
247 fn principal_def_id(self) -> Option<DefId> {
248 self.principal_def_id()
249 }
250
251 fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
252 self.principal()
253 }
254
255 fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
256 self.auto_traits()
257 }
258
259 fn projection_bounds(
260 self,
261 ) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
262 self.projection_bounds()
263 }
264}
265
266impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
267 pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
293 self[0]
294 .map_bound(|this| match this {
295 ExistentialPredicate::Trait(tr) => Some(tr),
296 _ => None,
297 })
298 .transpose()
299 }
300
301 pub fn principal_def_id(&self) -> Option<DefId> {
302 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
303 }
304
305 #[inline]
306 pub fn projection_bounds(
307 &self,
308 ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
309 self.iter().filter_map(|predicate| {
310 predicate
311 .map_bound(|pred| match pred {
312 ExistentialPredicate::Projection(projection) => Some(projection),
313 _ => None,
314 })
315 .transpose()
316 })
317 }
318
319 #[inline]
320 pub fn auto_traits(&self) -> impl Iterator<Item = DefId> {
321 self.iter().filter_map(|predicate| match predicate.skip_binder() {
322 ExistentialPredicate::AutoTrait(did) => Some(did),
323 _ => None,
324 })
325 }
326
327 pub fn without_auto_traits(&self) -> impl Iterator<Item = ty::PolyExistentialPredicate<'tcx>> {
328 self.iter().filter(|predicate| {
329 !#[allow(non_exhaustive_omitted_patterns)] match predicate.as_ref().skip_binder()
{
ExistentialPredicate::AutoTrait(_) => true,
_ => false,
}matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_))
330 })
331 }
332}
333
334pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
335pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;
336pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;
337
338impl<'tcx> Clause<'tcx> {
339 pub fn instantiate_supertrait(
345 self,
346 tcx: TyCtxt<'tcx>,
347 trait_ref: ty::PolyTraitRef<'tcx>,
348 ) -> Clause<'tcx> {
349 let bound_pred = self.kind();
424 let pred_bound_vars = bound_pred.bound_vars();
425 let trait_bound_vars = trait_ref.bound_vars();
426 let shifted_pred =
428 tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
429 let new = EarlyBinder::bind(tcx, shifted_pred)
431 .instantiate(tcx, trait_ref.skip_binder().args)
432 .skip_norm_wip();
433 let bound_vars =
435 tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
436
437 tcx.reuse_or_mk_predicate(
439 self.as_predicate(),
440 ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
441 )
442 .expect_clause()
443 }
444}
445
446impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> {
447 fn upcast_from(from: PredicateKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
448 ty::Binder::dummy(from).upcast(tcx)
449 }
450}
451
452impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> {
453 fn upcast_from(from: ty::Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
454 tcx.mk_predicate(from)
455 }
456}
457
458impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> {
459 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
460 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from)))
461 }
462}
463
464impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> {
465 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
466 tcx.mk_predicate(from.map_bound(PredicateKind::Clause))
467 }
468}
469
470impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> {
471 fn upcast_from(from: Clause<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
472 from.as_predicate()
473 }
474}
475
476impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> {
477 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
478 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))).expect_clause()
479 }
480}
481
482impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> {
483 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
484 tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause()
485 }
486}
487
488impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
489 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
490 ty::Binder::dummy(from).upcast(tcx)
491 }
492}
493
494impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
495 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
496 let p: Predicate<'tcx> = from.upcast(tcx);
497 p.expect_clause()
498 }
499}
500
501impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> {
502 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
503 let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
504 pred.upcast(tcx)
505 }
506}
507
508impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> {
509 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
510 let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
511 pred.upcast(tcx)
512 }
513}
514
515impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Predicate<'tcx> {
516 fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
517 PredicateKind::Clause(ClauseKind::Trait(from)).upcast(tcx)
518 }
519}
520
521impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Predicate<'tcx> {
522 fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
523 from.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).upcast(tcx)
524 }
525}
526
527impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Clause<'tcx> {
528 fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
529 let p: Predicate<'tcx> = from.upcast(tcx);
530 p.expect_clause()
531 }
532}
533
534impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> {
535 fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
536 let p: Predicate<'tcx> = from.upcast(tcx);
537 p.expect_clause()
538 }
539}
540
541impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesClause<'tcx>> for Predicate<'tcx> {
542 fn upcast_from(from: RegionOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
543 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
544 }
545}
546
547impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesClause<'tcx>> for Predicate<'tcx> {
548 fn upcast_from(from: PolyRegionOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
549 from.map_bound(|c| PredicateKind::Clause(ClauseKind::RegionOutlives(c))).upcast(tcx)
550 }
551}
552
553impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TypeOutlivesClause<'tcx>> for Predicate<'tcx> {
554 fn upcast_from(from: TypeOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
555 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx)
556 }
557}
558
559impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Predicate<'tcx> {
560 fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
561 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(from))).upcast(tcx)
562 }
563}
564
565impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Predicate<'tcx> {
566 fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
567 from.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).upcast(tcx)
568 }
569}
570
571impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Clause<'tcx> {
572 fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
573 let p: Predicate<'tcx> = from.upcast(tcx);
574 p.expect_clause()
575 }
576}
577
578impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Clause<'tcx> {
579 fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
580 let p: Predicate<'tcx> = from.upcast(tcx);
581 p.expect_clause()
582 }
583}
584
585impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectClause<'tcx>>>
586 for Predicate<'tcx>
587{
588 fn upcast_from(from: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
589 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
590 }
591}
592
593impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectClause<'tcx>>> for Clause<'tcx> {
594 fn upcast_from(from: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
595 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
596 }
597}
598
599impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> {
600 fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
601 PredicateKind::NormalizesTo(from).upcast(tcx)
602 }
603}
604
605impl<'tcx> Predicate<'tcx> {
606 pub fn as_trait_clause(self) -> Option<PolyTraitPredicate<'tcx>> {
607 let predicate = self.kind();
608 match predicate.skip_binder() {
609 PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
610 _ => None,
611 }
612 }
613
614 pub fn as_projection_clause(self) -> Option<PolyProjectionPredicate<'tcx>> {
615 let predicate = self.kind();
616 match predicate.skip_binder() {
617 PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
618 _ => None,
619 }
620 }
621
622 pub fn as_clause(self) -> Option<Clause<'tcx>> {
624 match self.kind().skip_binder() {
625 PredicateKind::Clause(..) => Some(self.expect_clause()),
626 _ => None,
627 }
628 }
629
630 pub fn expect_clause(self) -> Clause<'tcx> {
632 match self.kind().skip_binder() {
633 PredicateKind::Clause(..) => Clause(self.0),
634 _ => crate::util::bug::bug_fmt(format_args!("{0} is not a clause", self))bug!("{self} is not a clause"),
635 }
636 }
637}
638
639#[cfg(target_pointer_width = "64")]
641mod size_asserts {
642 use rustc_data_structures::static_assert_size;
643
644 use super::*;
645 const _: [(); 40] = [(); ::std::mem::size_of::<PredicateKind<'_>>()];static_assert_size!(PredicateKind<'_>, 40);
647 const _: [(); 48] =
[(); ::std::mem::size_of::<WithCachedTypeInfo<PredicateKind<'_>>>()];static_assert_size!(WithCachedTypeInfo<PredicateKind<'_>>, 48);
648 }