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