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 HostEffectPredicate<'tcx> = ir::HostEffectPredicate<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 OutlivesPredicate<'tcx, T> = ir::OutlivesPredicate<TyCtxt<'tcx>, T>;
25pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, ty::Region<'tcx>>;
26pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, Ty<'tcx>>;
27pub type ArgOutlivesPredicate<'tcx> = OutlivesPredicate<'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 PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
32pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'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, TypeOutlivesPredicate<'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(
208 self,
209 ) -> Option<ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>> {
210 let clause = self.kind();
211 if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() {
212 Some(clause.rebind(o))
213 } else {
214 None
215 }
216 }
217}
218
219impl<'tcx> rustc_type_ir::inherent::Clauses<TyCtxt<'tcx>> for ty::Clauses<'tcx> {}
220
221impl<'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>)]
222impl<'tcx> ExistentialPredicate<'tcx> {
223 fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
226 match (*self, *other) {
227 (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
228 (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => {
229 tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
230 }
231 (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => {
232 tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
233 }
234 (ExistentialPredicate::Trait(_), _) => Ordering::Less,
235 (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => {
236 Ordering::Greater
237 }
238 (ExistentialPredicate::Projection(_), _) => Ordering::Less,
239 (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
240 }
241 }
242}
243
244pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
245
246impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
247 for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
248{
249 fn principal_def_id(self) -> Option<DefId> {
250 self.principal_def_id()
251 }
252
253 fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
254 self.principal()
255 }
256
257 fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
258 self.auto_traits()
259 }
260
261 fn projection_bounds(
262 self,
263 ) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
264 self.projection_bounds()
265 }
266}
267
268impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
269 pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
295 self[0]
296 .map_bound(|this| match this {
297 ExistentialPredicate::Trait(tr) => Some(tr),
298 _ => None,
299 })
300 .transpose()
301 }
302
303 pub fn principal_def_id(&self) -> Option<DefId> {
304 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
305 }
306
307 #[inline]
308 pub fn projection_bounds(
309 &self,
310 ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
311 self.iter().filter_map(|predicate| {
312 predicate
313 .map_bound(|pred| match pred {
314 ExistentialPredicate::Projection(projection) => Some(projection),
315 _ => None,
316 })
317 .transpose()
318 })
319 }
320
321 #[inline]
322 pub fn auto_traits(&self) -> impl Iterator<Item = DefId> {
323 self.iter().filter_map(|predicate| match predicate.skip_binder() {
324 ExistentialPredicate::AutoTrait(did) => Some(did),
325 _ => None,
326 })
327 }
328
329 pub fn without_auto_traits(&self) -> impl Iterator<Item = ty::PolyExistentialPredicate<'tcx>> {
330 self.iter().filter(|predicate| {
331 !#[allow(non_exhaustive_omitted_patterns)] match predicate.as_ref().skip_binder()
{
ExistentialPredicate::AutoTrait(_) => true,
_ => false,
}matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_))
332 })
333 }
334}
335
336pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
337pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;
338pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;
339
340impl<'tcx> Clause<'tcx> {
341 pub fn instantiate_supertrait(
347 self,
348 tcx: TyCtxt<'tcx>,
349 trait_ref: ty::PolyTraitRef<'tcx>,
350 ) -> Clause<'tcx> {
351 let bound_pred = self.kind();
426 let pred_bound_vars = bound_pred.bound_vars();
427 let trait_bound_vars = trait_ref.bound_vars();
428 let shifted_pred =
430 tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
431 let new = EarlyBinder::bind(tcx, shifted_pred)
433 .instantiate(tcx, trait_ref.skip_binder().args)
434 .skip_norm_wip();
435 let bound_vars =
437 tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
438
439 tcx.reuse_or_mk_predicate(
441 self.as_predicate(),
442 ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
443 )
444 .expect_clause()
445 }
446}
447
448impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> {
449 fn upcast_from(from: PredicateKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
450 ty::Binder::dummy(from).upcast(tcx)
451 }
452}
453
454impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> {
455 fn upcast_from(from: ty::Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
456 tcx.mk_predicate(from)
457 }
458}
459
460impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> {
461 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
462 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from)))
463 }
464}
465
466impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> {
467 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
468 tcx.mk_predicate(from.map_bound(PredicateKind::Clause))
469 }
470}
471
472impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> {
473 fn upcast_from(from: Clause<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
474 from.as_predicate()
475 }
476}
477
478impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> {
479 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
480 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))).expect_clause()
481 }
482}
483
484impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> {
485 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
486 tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause()
487 }
488}
489
490impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
491 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
492 ty::Binder::dummy(from).upcast(tcx)
493 }
494}
495
496impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
497 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
498 let p: Predicate<'tcx> = from.upcast(tcx);
499 p.expect_clause()
500 }
501}
502
503impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> {
504 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
505 let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
506 pred.upcast(tcx)
507 }
508}
509
510impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> {
511 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
512 let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
513 pred.upcast(tcx)
514 }
515}
516
517impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Predicate<'tcx> {
518 fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
519 PredicateKind::Clause(ClauseKind::Trait(from)).upcast(tcx)
520 }
521}
522
523impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Predicate<'tcx> {
524 fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
525 from.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).upcast(tcx)
526 }
527}
528
529impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Clause<'tcx> {
530 fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
531 let p: Predicate<'tcx> = from.upcast(tcx);
532 p.expect_clause()
533 }
534}
535
536impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> {
537 fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
538 let p: Predicate<'tcx> = from.upcast(tcx);
539 p.expect_clause()
540 }
541}
542
543impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
544 fn upcast_from(from: RegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
545 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
546 }
547}
548
549impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
550 fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
551 from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx)
552 }
553}
554
555impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TypeOutlivesPredicate<'tcx>> for Predicate<'tcx> {
556 fn upcast_from(from: TypeOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
557 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx)
558 }
559}
560
561impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Predicate<'tcx> {
562 fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
563 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(from))).upcast(tcx)
564 }
565}
566
567impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Predicate<'tcx> {
568 fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
569 from.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).upcast(tcx)
570 }
571}
572
573impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Clause<'tcx> {
574 fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
575 let p: Predicate<'tcx> = from.upcast(tcx);
576 p.expect_clause()
577 }
578}
579
580impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Clause<'tcx> {
581 fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
582 let p: Predicate<'tcx> = from.upcast(tcx);
583 p.expect_clause()
584 }
585}
586
587impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
588 for Predicate<'tcx>
589{
590 fn upcast_from(
591 from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
592 tcx: TyCtxt<'tcx>,
593 ) -> Self {
594 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
595 }
596}
597
598impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
599 for Clause<'tcx>
600{
601 fn upcast_from(
602 from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
603 tcx: TyCtxt<'tcx>,
604 ) -> Self {
605 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
606 }
607}
608
609impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> {
610 fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
611 PredicateKind::NormalizesTo(from).upcast(tcx)
612 }
613}
614
615impl<'tcx> Predicate<'tcx> {
616 pub fn as_trait_clause(self) -> Option<PolyTraitPredicate<'tcx>> {
617 let predicate = self.kind();
618 match predicate.skip_binder() {
619 PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
620 _ => None,
621 }
622 }
623
624 pub fn as_projection_clause(self) -> Option<PolyProjectionPredicate<'tcx>> {
625 let predicate = self.kind();
626 match predicate.skip_binder() {
627 PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
628 _ => None,
629 }
630 }
631
632 pub fn as_clause(self) -> Option<Clause<'tcx>> {
634 match self.kind().skip_binder() {
635 PredicateKind::Clause(..) => Some(self.expect_clause()),
636 _ => None,
637 }
638 }
639
640 pub fn expect_clause(self) -> Clause<'tcx> {
642 match self.kind().skip_binder() {
643 PredicateKind::Clause(..) => Clause(self.0),
644 _ => crate::util::bug::bug_fmt(format_args!("{0} is not a clause", self))bug!("{self} is not a clause"),
645 }
646 }
647}
648
649#[cfg(target_pointer_width = "64")]
651mod size_asserts {
652 use rustc_data_structures::static_assert_size;
653
654 use super::*;
655 const _: [(); 40] = [(); ::std::mem::size_of::<PredicateKind<'_>>()];static_assert_size!(PredicateKind<'_>, 40);
657 const _: [(); 48] =
[(); ::std::mem::size_of::<WithCachedTypeInfo<PredicateKind<'_>>>()];static_assert_size!(WithCachedTypeInfo<PredicateKind<'_>>, 48);
658 }