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