1use std::cmp::Ordering;
2
3use rustc_data_structures::intern::Interned;
4use rustc_hir::def_id::DefId;
5use rustc_macros::{StableHash, extension};
6use rustc_span::bug;
7use rustc_type_ir as ir;
8
9use crate::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, WithCachedTypeInfo};
10
11pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
12pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>;
13pub type AliasTermKind<'tcx> = ir::AliasTermKind<TyCtxt<'tcx>>;
14pub type ProjectionClause<'tcx> = ir::ProjectionClause<TyCtxt<'tcx>>;
15pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
16pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
17pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
18pub type TraitClause<'tcx> = ir::TraitClause<TyCtxt<'tcx>>;
19pub type HostEffectClause<'tcx> = ir::HostEffectClause<TyCtxt<'tcx>>;
20pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
21pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
22pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
23pub type CoercePredicate<'tcx> = ir::CoercePredicate<TyCtxt<'tcx>>;
24pub type SubtypePredicate<'tcx> = ir::SubtypePredicate<TyCtxt<'tcx>>;
25pub type OutlivesClause<'tcx, T> = ir::OutlivesClause<TyCtxt<'tcx>, T>;
26pub type RegionOutlivesClause<'tcx> = OutlivesClause<'tcx, ty::Region<'tcx>>;
27pub type TypeOutlivesClause<'tcx> = OutlivesClause<'tcx, Ty<'tcx>>;
28pub type ArgOutlivesClause<'tcx> = OutlivesClause<'tcx, ty::GenericArg<'tcx>>;
29pub type RegionEqPredicate<'tcx> = ir::RegionEqPredicate<TyCtxt<'tcx>>;
30pub type RegionConstraint<'tcx> = ir::RegionConstraint<TyCtxt<'tcx>>;
31pub type PolyTraitClause<'tcx> = ty::Binder<'tcx, TraitClause<'tcx>>;
32pub type PolyRegionOutlivesClause<'tcx> = ty::Binder<'tcx, RegionOutlivesClause<'tcx>>;
33pub type PolyTypeOutlivesClause<'tcx> = ty::Binder<'tcx, TypeOutlivesClause<'tcx>>;
34pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
35pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
36pub type PolyProjectionClause<'tcx> = ty::Binder<'tcx, ProjectionClause<'tcx>>;
37
38#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for Predicate<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Predicate<'tcx> {
#[inline]
fn clone(&self) -> Self {
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::marker::StructuralPartialEq for Predicate<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Predicate<'tcx> {
#[inline]
fn eq(&self, other: &Self) -> 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)]
45#[rustc_pass_by_value]
46pub struct Predicate<'tcx>(
47 pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
48);
49
50impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {
51 fn as_clause(self) -> Option<ty::Clause<'tcx>> {
52 self.as_clause()
53 }
54}
55
56impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> {
57 type Kind = ty::Binder<'tcx, ty::PredicateKind<'tcx>>;
58
59 fn kind(self) -> Self::Kind {
60 self.kind()
61 }
62}
63
64impl<'tcx> rustc_type_ir::Flags for Predicate<'tcx> {
65 fn flags(&self) -> TypeFlags {
66 self.0.flags
67 }
68
69 fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
70 self.0.outer_exclusive_binder
71 }
72}
73
74impl<'tcx> Predicate<'tcx> {
75 #[inline]
77 pub fn kind(self) -> ty::Binder<'tcx, PredicateKind<'tcx>> {
78 self.0.internee
79 }
80
81 pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
85 let kind = self
86 .kind()
87 .map_bound(|kind| match kind {
88 PredicateKind::Clause(ClauseKind::Trait(TraitClause { trait_ref, polarity })) => {
89 Some(PredicateKind::Clause(ClauseKind::Trait(TraitClause {
90 trait_ref,
91 polarity: polarity.flip(),
92 })))
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]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for Clause<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Clause<'tcx> {
#[inline]
fn clone(&self) -> Self {
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::marker::StructuralPartialEq for Clause<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Clause<'tcx> {
#[inline]
fn eq(&self, other: &Self) -> 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 #[cold]
177 #[inline(never)]
178 fn unreachable_inner() -> ! {
179 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
180 }
181
182 self.0.internee.map_bound_no_validate_bound_vars(|kind| match kind {
183 PredicateKind::Clause(clause) => clause,
184 _ => unreachable_inner(),
185 })
186 }
187
188 pub fn as_trait_clause(self) -> Option<ty::Binder<'tcx, TraitClause<'tcx>>> {
189 let clause = self.kind();
190 if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() {
191 Some(clause.rebind(trait_clause))
192 } else {
193 None
194 }
195 }
196
197 pub fn as_projection_clause(self) -> Option<ty::Binder<'tcx, ProjectionClause<'tcx>>> {
198 let clause = self.kind();
199 if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() {
200 Some(clause.rebind(projection_clause))
201 } else {
202 None
203 }
204 }
205
206 pub fn as_type_outlives_clause(self) -> Option<ty::Binder<'tcx, TypeOutlivesClause<'tcx>>> {
207 let clause = self.kind();
208 if let ty::ClauseKind::TypeOutlives(o) = clause.skip_binder() {
209 Some(clause.rebind(o))
210 } else {
211 None
212 }
213 }
214
215 pub fn as_region_outlives_clause(self) -> Option<ty::Binder<'tcx, RegionOutlivesClause<'tcx>>> {
216 let clause = self.kind();
217 if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() {
218 Some(clause.rebind(o))
219 } else {
220 None
221 }
222 }
223}
224
225impl<'tcx> rustc_type_ir::inherent::Clauses<TyCtxt<'tcx>> for ty::Clauses<'tcx> {}
226
227pub trait ExistentialPredicateStableCmpExt<'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;
}
impl<'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>)]
228impl<'tcx> ExistentialPredicate<'tcx> {
229 fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
232 match (*self, *other) {
233 (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
234 (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => {
235 tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
236 }
237 (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => {
238 tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
239 }
240 (ExistentialPredicate::Trait(_), _) => Ordering::Less,
241 (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => {
242 Ordering::Greater
243 }
244 (ExistentialPredicate::Projection(_), _) => Ordering::Less,
245 (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
246 }
247 }
248}
249
250pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
251
252impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
253 for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
254{
255 fn principal_def_id(self) -> Option<DefId> {
256 self.principal_def_id()
257 }
258
259 fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
260 self.principal()
261 }
262
263 fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
264 self.auto_traits()
265 }
266
267 fn projection_bounds(
268 self,
269 ) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
270 self.projection_bounds()
271 }
272}
273
274impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
275 pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
301 self[0]
302 .map_bound(|this| match this {
303 ExistentialPredicate::Trait(tr) => Some(tr),
304 _ => None,
305 })
306 .transpose()
307 }
308
309 pub fn principal_def_id(&self) -> Option<DefId> {
310 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
311 }
312
313 #[inline]
314 pub fn projection_bounds(
315 &self,
316 ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
317 self.iter().filter_map(|predicate| {
318 predicate
319 .map_bound(|pred| match pred {
320 ExistentialPredicate::Projection(projection) => Some(projection),
321 _ => None,
322 })
323 .transpose()
324 })
325 }
326
327 #[inline]
328 pub fn auto_traits(&self) -> impl Iterator<Item = DefId> {
329 self.iter().filter_map(|predicate| match predicate.skip_binder() {
330 ExistentialPredicate::AutoTrait(did) => Some(did),
331 _ => None,
332 })
333 }
334
335 pub fn without_auto_traits(&self) -> impl Iterator<Item = ty::PolyExistentialPredicate<'tcx>> {
336 self.iter().filter(|predicate| {
337 !#[allow(non_exhaustive_omitted_patterns)] match predicate.as_ref().skip_binder()
{
ExistentialPredicate::AutoTrait(_) => true,
_ => false,
}matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_))
338 })
339 }
340}
341
342pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
343pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;
344pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;
345
346impl<'tcx> Clause<'tcx> {
347 pub fn instantiate_supertrait(
353 self,
354 tcx: TyCtxt<'tcx>,
355 trait_ref: ty::PolyTraitRef<'tcx>,
356 ) -> Clause<'tcx> {
357 let bound_pred = self.kind();
432 let pred_bound_vars = bound_pred.bound_vars();
433 let trait_bound_vars = trait_ref.bound_vars();
434 let shifted_pred =
436 tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
437 let new = EarlyBinder::bind(tcx, shifted_pred)
439 .instantiate(tcx, trait_ref.skip_binder().args)
440 .skip_norm_wip();
441 let bound_vars =
443 tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
444
445 tcx.reuse_or_mk_predicate(
447 self.as_predicate(),
448 ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
449 )
450 .expect_clause()
451 }
452}
453
454impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> {
455 fn upcast_from(from: PredicateKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
456 ty::Binder::dummy(from).upcast(tcx)
457 }
458}
459
460impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> {
461 fn upcast_from(from: ty::Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
462 tcx.mk_predicate(from)
463 }
464}
465
466impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> {
467 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
468 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from)))
469 }
470}
471
472impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> {
473 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
474 tcx.mk_predicate(from.map_bound(PredicateKind::Clause))
475 }
476}
477
478impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> {
479 fn upcast_from(from: Clause<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
480 from.as_predicate()
481 }
482}
483
484impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> {
485 fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
486 tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))).expect_clause()
487 }
488}
489
490impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> {
491 fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
492 tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause()
493 }
494}
495
496impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
497 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
498 ty::Binder::dummy(from).upcast(tcx)
499 }
500}
501
502impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
503 fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
504 let p: Predicate<'tcx> = from.upcast(tcx);
505 p.expect_clause()
506 }
507}
508
509impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> {
510 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
511 let pred: PolyTraitClause<'tcx> = from.upcast(tcx);
512 pred.upcast(tcx)
513 }
514}
515
516impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> {
517 fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
518 let pred: PolyTraitClause<'tcx> = from.upcast(tcx);
519 pred.upcast(tcx)
520 }
521}
522
523impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitClause<'tcx>> for Predicate<'tcx> {
524 fn upcast_from(from: TraitClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
525 PredicateKind::Clause(ClauseKind::Trait(from)).upcast(tcx)
526 }
527}
528
529impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitClause<'tcx>> for Predicate<'tcx> {
530 fn upcast_from(from: PolyTraitClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
531 from.map_bound_no_validate_bound_vars(|p| PredicateKind::Clause(ClauseKind::Trait(p)))
532 .upcast(tcx)
533 }
534}
535
536impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitClause<'tcx>> for Clause<'tcx> {
537 fn upcast_from(from: TraitClause<'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>, PolyTraitClause<'tcx>> for Clause<'tcx> {
544 fn upcast_from(from: PolyTraitClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
545 let p: Predicate<'tcx> = from.upcast(tcx);
546 p.expect_clause()
547 }
548}
549
550impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesClause<'tcx>> for Predicate<'tcx> {
551 fn upcast_from(from: RegionOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
552 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
553 }
554}
555
556impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesClause<'tcx>> for Predicate<'tcx> {
557 fn upcast_from(from: PolyRegionOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
558 from.map_bound(|c| PredicateKind::Clause(ClauseKind::RegionOutlives(c))).upcast(tcx)
559 }
560}
561
562impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TypeOutlivesClause<'tcx>> for Predicate<'tcx> {
563 fn upcast_from(from: TypeOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
564 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx)
565 }
566}
567
568impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionClause<'tcx>> for Predicate<'tcx> {
569 fn upcast_from(from: ProjectionClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
570 ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(from))).upcast(tcx)
571 }
572}
573
574impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionClause<'tcx>> for Predicate<'tcx> {
575 fn upcast_from(from: PolyProjectionClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
576 from.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).upcast(tcx)
577 }
578}
579
580impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionClause<'tcx>> for Clause<'tcx> {
581 fn upcast_from(from: ProjectionClause<'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>, PolyProjectionClause<'tcx>> for Clause<'tcx> {
588 fn upcast_from(from: PolyProjectionClause<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
589 let p: Predicate<'tcx> = from.upcast(tcx);
590 p.expect_clause()
591 }
592}
593
594impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectClause<'tcx>>>
595 for Predicate<'tcx>
596{
597 fn upcast_from(from: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
598 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
599 }
600}
601
602impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectClause<'tcx>>> for Clause<'tcx> {
603 fn upcast_from(from: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
604 from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
605 }
606}
607
608impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> {
609 fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
610 PredicateKind::NormalizesTo(from).upcast(tcx)
611 }
612}
613
614impl<'tcx> Predicate<'tcx> {
615 pub fn as_trait_clause(self) -> Option<PolyTraitClause<'tcx>> {
616 let predicate = self.kind();
617 match predicate.skip_binder() {
618 PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
619 _ => None,
620 }
621 }
622
623 pub fn as_projection_clause(self) -> Option<PolyProjectionClause<'tcx>> {
624 let predicate = self.kind();
625 match predicate.skip_binder() {
626 PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
627 _ => None,
628 }
629 }
630
631 pub fn as_clause(self) -> Option<Clause<'tcx>> {
633 match self.kind().skip_binder() {
634 PredicateKind::Clause(..) => Some(self.expect_clause()),
635 _ => None,
636 }
637 }
638
639 pub fn expect_clause(self) -> Clause<'tcx> {
641 match self.kind().skip_binder() {
642 PredicateKind::Clause(..) => Clause(self.0),
643 _ => ::rustc_span::macros::bug_impl(None,
format_args!("{0} is not a clause", self), Location::caller())bug!("{self} is not a clause"),
644 }
645 }
646}
647
648#[cfg(target_pointer_width = "64")]
650mod size_asserts {
651 use rustc_data_structures::static_assert_size;
652
653 use super::*;
654 const _: [(); 40] = [(); ::std::mem::size_of::<PredicateKind<'_>>()];static_assert_size!(PredicateKind<'_>, 40);
656 const _: [(); 48] =
[(); ::std::mem::size_of::<WithCachedTypeInfo<PredicateKind<'_>>>()];static_assert_size!(WithCachedTypeInfo<PredicateKind<'_>>, 48);
657 }