rustc_middle/ty/
predicate.rs

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