rustc_middle/ty/
predicate.rs

1use std::cmp::Ordering;
2
3use rustc_data_structures::intern::Interned;
4use rustc_hir::def_id::DefId;
5use rustc_macros::{HashStable, extension};
6use rustc_type_ir as ir;
7
8use crate::ty::{
9    self, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom,
10    WithCachedTypeInfo,
11};
12
13pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
14pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>;
15pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>;
16pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
17pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
18pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
19pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
20pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate<TyCtxt<'tcx>>;
21pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
22pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
23pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
24pub type CoercePredicate<'tcx> = ir::CoercePredicate<TyCtxt<'tcx>>;
25pub type SubtypePredicate<'tcx> = ir::SubtypePredicate<TyCtxt<'tcx>>;
26pub type OutlivesPredicate<'tcx, T> = ir::OutlivesPredicate<TyCtxt<'tcx>, T>;
27pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, ty::Region<'tcx>>;
28pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, Ty<'tcx>>;
29pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
30pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
31pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
32pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
33pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
34pub type PolyProjectionPredicate<'tcx> = ty::Binder<'tcx, ProjectionPredicate<'tcx>>;
35
36/// A statement that can be proven by a trait solver. This includes things that may
37/// show up in where clauses, such as trait predicates and projection predicates,
38/// and also things that are emitted as part of type checking such as `DynCompatible`
39/// predicate which is emitted when a type is coerced to a trait object.
40///
41/// Use this rather than `PredicateKind`, whenever possible.
42#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
43#[rustc_pass_by_value]
44pub struct Predicate<'tcx>(
45    pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
46);
47
48impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {
49    fn as_clause(self) -> Option<ty::Clause<'tcx>> {
50        self.as_clause()
51    }
52
53    fn allow_normalization(self) -> bool {
54        self.allow_normalization()
55    }
56}
57
58impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> {
59    type Kind = ty::Binder<'tcx, ty::PredicateKind<'tcx>>;
60
61    fn kind(self) -> Self::Kind {
62        self.kind()
63    }
64}
65
66impl<'tcx> rustc_type_ir::Flags for Predicate<'tcx> {
67    fn flags(&self) -> TypeFlags {
68        self.0.flags
69    }
70
71    fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
72        self.0.outer_exclusive_binder
73    }
74}
75
76impl<'tcx> Predicate<'tcx> {
77    /// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
78    #[inline]
79    pub fn kind(self) -> ty::Binder<'tcx, PredicateKind<'tcx>> {
80        self.0.internee
81    }
82
83    // FIXME(compiler-errors): Think about removing this.
84    #[inline(always)]
85    pub fn flags(self) -> TypeFlags {
86        self.0.flags
87    }
88
89    // FIXME(compiler-errors): Think about removing this.
90    #[inline(always)]
91    pub fn outer_exclusive_binder(self) -> DebruijnIndex {
92        self.0.outer_exclusive_binder
93    }
94
95    /// Flips the polarity of a Predicate.
96    ///
97    /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
98    pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
99        let kind = self
100            .kind()
101            .map_bound(|kind| match kind {
102                PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
103                    trait_ref,
104                    polarity,
105                })) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
106                    trait_ref,
107                    polarity: polarity.flip(),
108                }))),
109
110                _ => None,
111            })
112            .transpose()?;
113
114        Some(tcx.mk_predicate(kind))
115    }
116
117    /// Whether this projection can be soundly normalized.
118    ///
119    /// Wf predicates must not be normalized, as normalization
120    /// can remove required bounds which would cause us to
121    /// unsoundly accept some programs. See #91068.
122    #[inline]
123    pub fn allow_normalization(self) -> bool {
124        match self.kind().skip_binder() {
125            PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
126                false
127            }
128            PredicateKind::Clause(ClauseKind::Trait(_))
129            | PredicateKind::Clause(ClauseKind::HostEffect(..))
130            | PredicateKind::Clause(ClauseKind::RegionOutlives(_))
131            | PredicateKind::Clause(ClauseKind::TypeOutlives(_))
132            | PredicateKind::Clause(ClauseKind::Projection(_))
133            | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
134            | PredicateKind::DynCompatible(_)
135            | PredicateKind::Subtype(_)
136            | PredicateKind::Coerce(_)
137            | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
138            | PredicateKind::ConstEquate(_, _)
139            | PredicateKind::NormalizesTo(..)
140            | PredicateKind::Ambiguous => true,
141        }
142    }
143}
144
145impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> {
146    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
147        ty::tls::with(|tcx| {
148            let pred = tcx.short_string(self, path);
149            rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred))
150        })
151    }
152}
153
154impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> {
155    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
156        ty::tls::with(|tcx| {
157            let clause = tcx.short_string(self, path);
158            rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause))
159        })
160    }
161}
162
163/// A subset of predicates which can be assumed by the trait solver. They show up in
164/// an item's where clauses, hence the name `Clause`, and may either be user-written
165/// (such as traits) or may be inserted during lowering.
166#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
167#[rustc_pass_by_value]
168pub struct Clause<'tcx>(
169    pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
170);
171
172impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
173    fn as_predicate(self) -> Predicate<'tcx> {
174        self.as_predicate()
175    }
176
177    fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
178        self.instantiate_supertrait(tcx, trait_ref)
179    }
180}
181
182impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
183    type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
184
185    fn kind(self) -> Self::Kind {
186        self.kind()
187    }
188}
189
190impl<'tcx> Clause<'tcx> {
191    pub fn as_predicate(self) -> Predicate<'tcx> {
192        Predicate(self.0)
193    }
194
195    pub fn kind(self) -> ty::Binder<'tcx, ClauseKind<'tcx>> {
196        self.0.internee.map_bound(|kind| match kind {
197            PredicateKind::Clause(clause) => clause,
198            _ => unreachable!(),
199        })
200    }
201
202    pub fn as_trait_clause(self) -> Option<ty::Binder<'tcx, TraitPredicate<'tcx>>> {
203        let clause = self.kind();
204        if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() {
205            Some(clause.rebind(trait_clause))
206        } else {
207            None
208        }
209    }
210
211    pub fn as_projection_clause(self) -> Option<ty::Binder<'tcx, ProjectionPredicate<'tcx>>> {
212        let clause = self.kind();
213        if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() {
214            Some(clause.rebind(projection_clause))
215        } else {
216            None
217        }
218    }
219
220    pub fn as_type_outlives_clause(self) -> Option<ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>> {
221        let clause = self.kind();
222        if let ty::ClauseKind::TypeOutlives(o) = clause.skip_binder() {
223            Some(clause.rebind(o))
224        } else {
225            None
226        }
227    }
228
229    pub fn as_region_outlives_clause(
230        self,
231    ) -> Option<ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>> {
232        let clause = self.kind();
233        if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() {
234            Some(clause.rebind(o))
235        } else {
236            None
237        }
238    }
239}
240
241impl<'tcx> rustc_type_ir::inherent::Clauses<TyCtxt<'tcx>> for ty::Clauses<'tcx> {}
242
243#[extension(pub trait ExistentialPredicateStableCmpExt<'tcx>)]
244impl<'tcx> ExistentialPredicate<'tcx> {
245    /// Compares via an ordering that will not change if modules are reordered or other changes are
246    /// made to the tree. In particular, this ordering is preserved across incremental compilations.
247    fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
248        match (*self, *other) {
249            (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal,
250            (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => {
251                tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
252            }
253            (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => {
254                tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
255            }
256            (ExistentialPredicate::Trait(_), _) => Ordering::Less,
257            (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => {
258                Ordering::Greater
259            }
260            (ExistentialPredicate::Projection(_), _) => Ordering::Less,
261            (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater,
262        }
263    }
264}
265
266pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
267
268impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
269    for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
270{
271    fn principal_def_id(self) -> Option<DefId> {
272        self.principal_def_id()
273    }
274
275    fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
276        self.principal()
277    }
278
279    fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
280        self.auto_traits()
281    }
282
283    fn projection_bounds(
284        self,
285    ) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
286        self.projection_bounds()
287    }
288}
289
290impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
291    /// Returns the "principal `DefId`" of this set of existential predicates.
292    ///
293    /// A Rust trait object type consists (in addition to a lifetime bound)
294    /// of a set of trait bounds, which are separated into any number
295    /// of auto-trait bounds, and at most one non-auto-trait bound. The
296    /// non-auto-trait bound is called the "principal" of the trait
297    /// object.
298    ///
299    /// Only the principal can have methods or type parameters (because
300    /// auto traits can have neither of them). This is important, because
301    /// it means the auto traits can be treated as an unordered set (methods
302    /// would force an order for the vtable, while relating traits with
303    /// type parameters without knowing the order to relate them in is
304    /// a rather non-trivial task).
305    ///
306    /// For example, in the trait object `dyn std::fmt::Debug + Sync`, the
307    /// principal bound is `Some(std::fmt::Debug)`, while the auto-trait bounds
308    /// are the set `{Sync}`.
309    ///
310    /// It is also possible to have a "trivial" trait object that
311    /// consists only of auto traits, with no principal - for example,
312    /// `dyn Send + Sync`. In that case, the set of auto-trait bounds
313    /// is `{Send, Sync}`, while there is no principal. These trait objects
314    /// have a "trivial" vtable consisting of just the size, alignment,
315    /// and destructor.
316    pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
317        self[0]
318            .map_bound(|this| match this {
319                ExistentialPredicate::Trait(tr) => Some(tr),
320                _ => None,
321            })
322            .transpose()
323    }
324
325    pub fn principal_def_id(&self) -> Option<DefId> {
326        self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
327    }
328
329    #[inline]
330    pub fn projection_bounds(
331        &self,
332    ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
333        self.iter().filter_map(|predicate| {
334            predicate
335                .map_bound(|pred| match pred {
336                    ExistentialPredicate::Projection(projection) => Some(projection),
337                    _ => None,
338                })
339                .transpose()
340        })
341    }
342
343    #[inline]
344    pub fn auto_traits(&self) -> impl Iterator<Item = DefId> {
345        self.iter().filter_map(|predicate| match predicate.skip_binder() {
346            ExistentialPredicate::AutoTrait(did) => Some(did),
347            _ => None,
348        })
349    }
350
351    pub fn without_auto_traits(&self) -> impl Iterator<Item = ty::PolyExistentialPredicate<'tcx>> {
352        self.iter().filter(|predicate| {
353            !matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_))
354        })
355    }
356}
357
358pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
359pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;
360pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;
361
362impl<'tcx> Clause<'tcx> {
363    /// Performs a instantiation suitable for going from a
364    /// poly-trait-ref to supertraits that must hold if that
365    /// poly-trait-ref holds. This is slightly different from a normal
366    /// instantiation in terms of what happens with bound regions. See
367    /// lengthy comment below for details.
368    pub fn instantiate_supertrait(
369        self,
370        tcx: TyCtxt<'tcx>,
371        trait_ref: ty::PolyTraitRef<'tcx>,
372    ) -> Clause<'tcx> {
373        // The interaction between HRTB and supertraits is not entirely
374        // obvious. Let me walk you (and myself) through an example.
375        //
376        // Let's start with an easy case. Consider two traits:
377        //
378        //     trait Foo<'a>: Bar<'a,'a> { }
379        //     trait Bar<'b,'c> { }
380        //
381        // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
382        // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
383        // knew that `Foo<'x>` (for any 'x) then we also know that
384        // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
385        // normal instantiation.
386        //
387        // In terms of why this is sound, the idea is that whenever there
388        // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
389        // holds. So if there is an impl of `T:Foo<'a>` that applies to
390        // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
391        // `'a`.
392        //
393        // Another example to be careful of is this:
394        //
395        //     trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
396        //     trait Bar1<'b,'c> { }
397        //
398        // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
399        // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
400        // reason is similar to the previous example: any impl of
401        // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So
402        // basically we would want to collapse the bound lifetimes from
403        // the input (`trait_ref`) and the supertraits.
404        //
405        // To achieve this in practice is fairly straightforward. Let's
406        // consider the more complicated scenario:
407        //
408        // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
409        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
410        //   where both `'x` and `'b` would have a DB index of 1.
411        //   The instantiation from the input trait-ref is therefore going to be
412        //   `'a => 'x` (where `'x` has a DB index of 1).
413        // - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
414        //   early-bound parameter and `'b` is a late-bound parameter with a
415        //   DB index of 1.
416        // - If we replace `'a` with `'x` from the input, it too will have
417        //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
418        //   just as we wanted.
419        //
420        // There is only one catch. If we just apply the instantiation `'a
421        // => 'x` to `for<'b> Bar1<'a,'b>`, the instantiation code will
422        // adjust the DB index because we instantiating into a binder (it
423        // tries to be so smart...) resulting in `for<'x> for<'b>
424        // Bar1<'x,'b>` (we have no syntax for this, so use your
425        // imagination). Basically the 'x will have DB index of 2 and 'b
426        // will have DB index of 1. Not quite what we want. So we apply
427        // the instantiation to the *contents* of the trait reference,
428        // rather than the trait reference itself (put another way, the
429        // instantiation code expects equal binding levels in the values
430        // from the instantiation and the value being instantiated into, and
431        // this trick achieves that).
432
433        // Working through the second example:
434        // trait_ref: for<'x> T: Foo1<'^0.0>; args: [T, '^0.0]
435        // predicate: for<'b> Self: Bar1<'a, '^0.0>; args: [Self, 'a, '^0.0]
436        // We want to end up with:
437        //     for<'x, 'b> T: Bar1<'^0.0, '^0.1>
438        // To do this:
439        // 1) We must shift all bound vars in predicate by the length
440        //    of trait ref's bound vars. So, we would end up with predicate like
441        //    Self: Bar1<'a, '^0.1>
442        // 2) We can then apply the trait args to this, ending up with
443        //    T: Bar1<'^0.0, '^0.1>
444        // 3) Finally, to create the final bound vars, we concatenate the bound
445        //    vars of the trait ref with those of the predicate:
446        //    ['x, 'b]
447        let bound_pred = self.kind();
448        let pred_bound_vars = bound_pred.bound_vars();
449        let trait_bound_vars = trait_ref.bound_vars();
450        // 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1>
451        let shifted_pred =
452            tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
453        // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
454        let new = EarlyBinder::bind(shifted_pred).instantiate(tcx, trait_ref.skip_binder().args);
455        // 3) ['x] + ['b] -> ['x, 'b]
456        let bound_vars =
457            tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
458
459        // FIXME: Is it really perf sensitive to use reuse_or_mk_predicate here?
460        tcx.reuse_or_mk_predicate(
461            self.as_predicate(),
462            ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
463        )
464        .expect_clause()
465    }
466}
467
468impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> {
469    fn upcast_from(from: PredicateKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
470        ty::Binder::dummy(from).upcast(tcx)
471    }
472}
473
474impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> {
475    fn upcast_from(from: ty::Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
476        tcx.mk_predicate(from)
477    }
478}
479
480impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> {
481    fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
482        tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from)))
483    }
484}
485
486impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> {
487    fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
488        tcx.mk_predicate(from.map_bound(PredicateKind::Clause))
489    }
490}
491
492impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> {
493    fn upcast_from(from: Clause<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
494        from.as_predicate()
495    }
496}
497
498impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> {
499    fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
500        tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))).expect_clause()
501    }
502}
503
504impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> {
505    fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
506        tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause()
507    }
508}
509
510impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
511    fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
512        ty::Binder::dummy(from).upcast(tcx)
513    }
514}
515
516impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
517    fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
518        let p: Predicate<'tcx> = from.upcast(tcx);
519        p.expect_clause()
520    }
521}
522
523impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> {
524    fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
525        let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
526        pred.upcast(tcx)
527    }
528}
529
530impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> {
531    fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self {
532        let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx);
533        pred.upcast(tcx)
534    }
535}
536
537impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for PolyTraitPredicate<'tcx> {
538    fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, _tcx: TyCtxt<'tcx>) -> Self {
539        from.map_bound(|trait_ref| TraitPredicate {
540            trait_ref,
541            polarity: PredicatePolarity::Positive,
542        })
543    }
544}
545
546impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Predicate<'tcx> {
547    fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
548        PredicateKind::Clause(ClauseKind::Trait(from)).upcast(tcx)
549    }
550}
551
552impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Predicate<'tcx> {
553    fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
554        from.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).upcast(tcx)
555    }
556}
557
558impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitPredicate<'tcx>> for Clause<'tcx> {
559    fn upcast_from(from: TraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
560        let p: Predicate<'tcx> = from.upcast(tcx);
561        p.expect_clause()
562    }
563}
564
565impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> {
566    fn upcast_from(from: PolyTraitPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
567        let p: Predicate<'tcx> = from.upcast(tcx);
568        p.expect_clause()
569    }
570}
571
572impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
573    fn upcast_from(from: RegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
574        ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
575    }
576}
577
578impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
579    fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
580        from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx)
581    }
582}
583
584impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TypeOutlivesPredicate<'tcx>> for Predicate<'tcx> {
585    fn upcast_from(from: TypeOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
586        ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx)
587    }
588}
589
590impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Predicate<'tcx> {
591    fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
592        ty::Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(from))).upcast(tcx)
593    }
594}
595
596impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Predicate<'tcx> {
597    fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
598        from.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).upcast(tcx)
599    }
600}
601
602impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ProjectionPredicate<'tcx>> for Clause<'tcx> {
603    fn upcast_from(from: ProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
604        let p: Predicate<'tcx> = from.upcast(tcx);
605        p.expect_clause()
606    }
607}
608
609impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyProjectionPredicate<'tcx>> for Clause<'tcx> {
610    fn upcast_from(from: PolyProjectionPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
611        let p: Predicate<'tcx> = from.upcast(tcx);
612        p.expect_clause()
613    }
614}
615
616impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
617    for Predicate<'tcx>
618{
619    fn upcast_from(
620        from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
621        tcx: TyCtxt<'tcx>,
622    ) -> Self {
623        from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
624    }
625}
626
627impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>>
628    for Clause<'tcx>
629{
630    fn upcast_from(
631        from: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
632        tcx: TyCtxt<'tcx>,
633    ) -> Self {
634        from.map_bound(ty::ClauseKind::HostEffect).upcast(tcx)
635    }
636}
637
638impl<'tcx> UpcastFrom<TyCtxt<'tcx>, NormalizesTo<'tcx>> for Predicate<'tcx> {
639    fn upcast_from(from: NormalizesTo<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
640        PredicateKind::NormalizesTo(from).upcast(tcx)
641    }
642}
643
644impl<'tcx> Predicate<'tcx> {
645    pub fn as_trait_clause(self) -> Option<PolyTraitPredicate<'tcx>> {
646        let predicate = self.kind();
647        match predicate.skip_binder() {
648            PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
649            PredicateKind::Clause(ClauseKind::Projection(..))
650            | PredicateKind::Clause(ClauseKind::HostEffect(..))
651            | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
652            | PredicateKind::NormalizesTo(..)
653            | PredicateKind::AliasRelate(..)
654            | PredicateKind::Subtype(..)
655            | PredicateKind::Coerce(..)
656            | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
657            | PredicateKind::Clause(ClauseKind::WellFormed(..))
658            | PredicateKind::DynCompatible(..)
659            | PredicateKind::Clause(ClauseKind::TypeOutlives(..))
660            | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
661            | PredicateKind::ConstEquate(..)
662            | PredicateKind::Ambiguous => None,
663        }
664    }
665
666    pub fn as_projection_clause(self) -> Option<PolyProjectionPredicate<'tcx>> {
667        let predicate = self.kind();
668        match predicate.skip_binder() {
669            PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
670            PredicateKind::Clause(ClauseKind::Trait(..))
671            | PredicateKind::Clause(ClauseKind::HostEffect(..))
672            | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
673            | PredicateKind::NormalizesTo(..)
674            | PredicateKind::AliasRelate(..)
675            | PredicateKind::Subtype(..)
676            | PredicateKind::Coerce(..)
677            | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
678            | PredicateKind::Clause(ClauseKind::WellFormed(..))
679            | PredicateKind::DynCompatible(..)
680            | PredicateKind::Clause(ClauseKind::TypeOutlives(..))
681            | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
682            | PredicateKind::ConstEquate(..)
683            | PredicateKind::Ambiguous => None,
684        }
685    }
686
687    /// Matches a `PredicateKind::Clause` and turns it into a `Clause`, otherwise returns `None`.
688    pub fn as_clause(self) -> Option<Clause<'tcx>> {
689        match self.kind().skip_binder() {
690            PredicateKind::Clause(..) => Some(self.expect_clause()),
691            _ => None,
692        }
693    }
694
695    /// Assert that the predicate is a clause.
696    pub fn expect_clause(self) -> Clause<'tcx> {
697        match self.kind().skip_binder() {
698            PredicateKind::Clause(..) => Clause(self.0),
699            _ => bug!("{self} is not a clause"),
700        }
701    }
702}