Skip to main content

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