Skip to main content

rustc_type_ir/
predicate.rs

1use std::fmt;
2use std::hash::Hash;
3
4use derive_where::derive_where;
5#[cfg(feature = "nightly")]
6use rustc_macros::{
7    Decodable, Decodable_NoContext, Encodable, Encodable_NoContext, HashStable_NoContext,
8};
9use rustc_type_ir_macros::{
10    GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
11};
12
13use crate::inherent::*;
14use crate::lift::Lift;
15use crate::upcast::{Upcast, UpcastFrom};
16use crate::visit::TypeVisitableExt as _;
17use crate::{self as ty, Interner};
18
19/// `A: 'region`
20#[automatically_derived]
impl<I: Interner, A> ::core::marker::Copy for OutlivesPredicate<I, A> where
    I: Interner, A: Copy {
}#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)]
21#[derive_where(Copy; I: Interner, A: Copy)]
22#[derive(const _: () =
    {
        impl<I: Interner, A> ::rustc_type_ir::TypeVisitable<I> for
            OutlivesPredicate<I, A> where I: Interner,
            A: ::rustc_type_ir::TypeVisitable<I>,
            I::Region: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    OutlivesPredicate(ref __binding_0, ref __binding_1) => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner, A> ::rustc_type_ir::TypeFoldable<I> for
            OutlivesPredicate<I, A> where I: Interner,
            A: ::rustc_type_ir::TypeFoldable<I>,
            I::Region: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        OutlivesPredicate(__binding_0, __binding_1) => {
                            OutlivesPredicate(::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?)
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    OutlivesPredicate(__binding_0, __binding_1) => {
                        OutlivesPredicate(::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable_Generic)]
23#[cfg_attr(
24    feature = "nightly",
25    derive(const _: () =
    {
        impl<I: Interner, A, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for OutlivesPredicate<I, A>
            where A: ::rustc_serialize::Decodable<__D>,
            I::Region: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                OutlivesPredicate(::rustc_serialize::Decodable::decode(__decoder),
                    ::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, A, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for OutlivesPredicate<I, A>
            where A: ::rustc_serialize::Encodable<__E>,
            I::Region: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    OutlivesPredicate(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, A, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            OutlivesPredicate<I, A> where
            A: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::Region: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    OutlivesPredicate(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
26)]
27pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
28
29impl<I: Interner, A: Eq> Eq for OutlivesPredicate<I, A> {}
30
31// FIXME: We manually derive `Lift` because the `derive(Lift_Generic)` doesn't
32// understand how to turn `A` to `A::Lifted` in the output `type Lifted`.
33impl<I: Interner, U: Interner, A> Lift<U> for OutlivesPredicate<I, A>
34where
35    A: Lift<U>,
36    I::Region: Lift<U, Lifted = U::Region>,
37{
38    type Lifted = OutlivesPredicate<U, A::Lifted>;
39
40    fn lift_to_interner(self, cx: U) -> Option<Self::Lifted> {
41        Some(OutlivesPredicate(self.0.lift_to_interner(cx)?, self.1.lift_to_interner(cx)?))
42    }
43}
44
45/// A complete reference to a trait.
46///
47/// These take numerous guises in syntax,
48/// but perhaps the most recognizable form is in a where-clause:
49/// ```ignore (illustrative)
50/// T: Foo<U>
51/// ```
52/// This would be represented by a trait-reference where the `DefId` is the
53/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
54/// and `U` as parameter 1.
55///
56/// Trait references also appear in object types like `Foo<U>`, but in
57/// that case the `Self` parameter is absent from the generic parameters.
58#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for TraitRef<I> where I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> bool {
        match (self, __other) {
            (TraitRef {
                def_id: ref __field_def_id,
                args: ref __field_args,
                _use_trait_ref_new_instead: ref __field__use_trait_ref_new_instead
                }, TraitRef {
                def_id: ref __other_field_def_id,
                args: ref __other_field_args,
                _use_trait_ref_new_instead: ref __other_field__use_trait_ref_new_instead
                }) =>
                true &&
                            ::core::cmp::PartialEq::eq(__field_def_id,
                                __other_field_def_id) &&
                        ::core::cmp::PartialEq::eq(__field_args, __other_field_args)
                    &&
                    ::core::cmp::PartialEq::eq(__field__use_trait_ref_new_instead,
                        __other_field__use_trait_ref_new_instead),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
59#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for TraitRef<I>
            where I: Interner, I::TraitId: ::rustc_type_ir::TypeVisitable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    TraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_trait_ref_new_instead: ref __binding_2 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for TraitRef<I>
            where I: Interner, I::TraitId: ::rustc_type_ir::TypeFoldable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        TraitRef {
                            def_id: __binding_0,
                            args: __binding_1,
                            _use_trait_ref_new_instead: __binding_2 } => {
                            TraitRef {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                args: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                _use_trait_ref_new_instead: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    TraitRef {
                        def_id: __binding_0,
                        args: __binding_1,
                        _use_trait_ref_new_instead: __binding_2 } => {
                        TraitRef {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            args: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            _use_trait_ref_new_instead: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for TraitRef<I>
            where I: Interner, J: Interner,
            I::TraitId: ::rustc_type_ir::lift::Lift<J, Lifted = J::TraitId>,
            I::GenericArgs: ::rustc_type_ir::lift::Lift<J, Lifted =
            J::GenericArgs>, (): ::rustc_type_ir::lift::Lift<J, Lifted = ()> {
            type Lifted = TraitRef<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        TraitRef {
                            def_id: __binding_0,
                            args: __binding_1,
                            _use_trait_ref_new_instead: __binding_2 } => {
                            TraitRef {
                                def_id: __binding_0.lift_to_interner(interner)?,
                                args: __binding_1.lift_to_interner(interner)?,
                                _use_trait_ref_new_instead: __binding_2.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
60#[cfg_attr(
61    feature = "nightly",
62    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for TraitRef<I> where
            I::TraitId: ::rustc_serialize::Decodable<__D>,
            I::GenericArgs: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                TraitRef {
                    def_id: ::rustc_serialize::Decodable::decode(__decoder),
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    _use_trait_ref_new_instead: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for TraitRef<I> where
            I::TraitId: ::rustc_serialize::Encodable<__E>,
            I::GenericArgs: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    TraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_trait_ref_new_instead: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            TraitRef<I> where
            I::TraitId: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::GenericArgs: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    TraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_trait_ref_new_instead: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
63)]
64pub struct TraitRef<I: Interner> {
65    pub def_id: I::TraitId,
66    pub args: I::GenericArgs,
67    /// This field exists to prevent the creation of `TraitRef` without
68    /// calling [`TraitRef::new_from_args`].
69    _use_trait_ref_new_instead: (),
70}
71
72impl<I: Interner> Eq for TraitRef<I> {}
73
74impl<I: Interner> TraitRef<I> {
75    pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
76        interner.debug_assert_args_compatible(trait_def_id.into(), args);
77        Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
78    }
79
80    pub fn new(
81        interner: I,
82        trait_def_id: I::TraitId,
83        args: impl IntoIterator<Item: Into<I::GenericArg>>,
84    ) -> Self {
85        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
86        Self::new_from_args(interner, trait_def_id, args)
87    }
88
89    pub fn from_assoc(interner: I, trait_id: I::TraitId, args: I::GenericArgs) -> TraitRef<I> {
90        let generics = interner.generics_of(trait_id.into());
91        TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
92    }
93
94    /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
95    /// are the parameters defined on trait.
96    pub fn identity(interner: I, def_id: I::TraitId) -> TraitRef<I> {
97        TraitRef::new_from_args(
98            interner,
99            def_id,
100            I::GenericArgs::identity_for_item(interner, def_id.into()),
101        )
102    }
103
104    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
105        TraitRef::new(
106            interner,
107            self.def_id,
108            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
109        )
110    }
111
112    #[inline]
113    pub fn self_ty(&self) -> I::Ty {
114        self.args.type_at(0)
115    }
116}
117
118impl<I: Interner> ty::Binder<I, TraitRef<I>> {
119    pub fn self_ty(&self) -> ty::Binder<I, I::Ty> {
120        self.map_bound_ref(|tr| tr.self_ty())
121    }
122
123    pub fn def_id(&self) -> I::TraitId {
124        self.skip_binder().def_id
125    }
126
127    pub fn to_host_effect_clause(self, cx: I, constness: BoundConstness) -> I::Clause {
128        self.map_bound(|trait_ref| {
129            ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
130        })
131        .upcast(cx)
132    }
133}
134
135#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for TraitPredicate<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> bool {
        match (self, __other) {
            (TraitPredicate {
                trait_ref: ref __field_trait_ref,
                polarity: ref __field_polarity }, TraitPredicate {
                trait_ref: ref __other_field_trait_ref,
                polarity: ref __other_field_polarity }) =>
                true &&
                        ::core::cmp::PartialEq::eq(__field_trait_ref,
                            __other_field_trait_ref) &&
                    ::core::cmp::PartialEq::eq(__field_polarity,
                        __other_field_polarity),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
136#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            TraitPredicate<I> where I: Interner,
            TraitRef<I>: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    TraitPredicate {
                        trait_ref: ref __binding_0, polarity: ref __binding_1 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            TraitPredicate<I> where I: Interner,
            TraitRef<I>: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        TraitPredicate {
                            trait_ref: __binding_0, polarity: __binding_1 } => {
                            TraitPredicate {
                                trait_ref: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                polarity: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    TraitPredicate {
                        trait_ref: __binding_0, polarity: __binding_1 } => {
                        TraitPredicate {
                            trait_ref: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            polarity: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            TraitPredicate<I> where I: Interner, J: Interner,
            TraitRef<I>: ::rustc_type_ir::lift::Lift<J, Lifted = TraitRef<J>>,
            PredicatePolarity: ::rustc_type_ir::lift::Lift<J, Lifted =
            PredicatePolarity> {
            type Lifted = TraitPredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        TraitPredicate {
                            trait_ref: __binding_0, polarity: __binding_1 } => {
                            TraitPredicate {
                                trait_ref: __binding_0.lift_to_interner(interner)?,
                                polarity: __binding_1.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
137#[cfg_attr(
138    feature = "nightly",
139    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for TraitPredicate<I> where
            TraitRef<I>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                TraitPredicate {
                    trait_ref: ::rustc_serialize::Decodable::decode(__decoder),
                    polarity: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for TraitPredicate<I> where
            TraitRef<I>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    TraitPredicate {
                        trait_ref: ref __binding_0, polarity: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            TraitPredicate<I> where
            TraitRef<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    TraitPredicate {
                        trait_ref: ref __binding_0, polarity: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
140)]
141pub struct TraitPredicate<I: Interner> {
142    pub trait_ref: TraitRef<I>,
143
144    /// If polarity is Positive: we are proving that the trait is implemented.
145    ///
146    /// If polarity is Negative: we are proving that a negative impl of this trait
147    /// exists. (Note that coherence also checks whether negative impls of supertraits
148    /// exist via a series of predicates.)
149    pub polarity: PredicatePolarity,
150}
151
152impl<I: Interner> Eq for TraitPredicate<I> {}
153
154impl<I: Interner> TraitPredicate<I> {
155    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
156        Self {
157            trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty),
158            polarity: self.polarity,
159        }
160    }
161
162    pub fn def_id(self) -> I::TraitId {
163        self.trait_ref.def_id
164    }
165
166    pub fn self_ty(self) -> I::Ty {
167        self.trait_ref.self_ty()
168    }
169}
170
171impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
172    pub fn def_id(self) -> I::TraitId {
173        // Ok to skip binder since trait `DefId` does not care about regions.
174        self.skip_binder().def_id()
175    }
176
177    pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
178        self.map_bound(|trait_ref| trait_ref.self_ty())
179    }
180
181    #[inline]
182    pub fn polarity(self) -> PredicatePolarity {
183        self.skip_binder().polarity
184    }
185}
186
187impl<I: Interner> UpcastFrom<I, TraitRef<I>> for TraitPredicate<I> {
188    fn upcast_from(from: TraitRef<I>, _tcx: I) -> Self {
189        TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
190    }
191}
192
193impl<I: Interner> UpcastFrom<I, ty::Binder<I, TraitRef<I>>> for ty::Binder<I, TraitPredicate<I>> {
194    fn upcast_from(from: ty::Binder<I, TraitRef<I>>, _tcx: I) -> Self {
195        from.map_bound(|trait_ref| TraitPredicate {
196            trait_ref,
197            polarity: PredicatePolarity::Positive,
198        })
199    }
200}
201
202impl<I: Interner> fmt::Debug for TraitPredicate<I> {
203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204        f.write_fmt(format_args!("TraitPredicate({0:?}, polarity:{1:?})",
        self.trait_ref, self.polarity))write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
205    }
206}
207
208#[derive(#[automatically_derived]
impl ::core::clone::Clone for ImplPolarity {
    #[inline]
    fn clone(&self) -> ImplPolarity { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ImplPolarity { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ImplPolarity {
    #[inline]
    fn eq(&self, other: &ImplPolarity) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ImplPolarity {
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for ImplPolarity {
    #[inline]
    fn partial_cmp(&self, other: &ImplPolarity)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for ImplPolarity {
    #[inline]
    fn cmp(&self, other: &ImplPolarity) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for ImplPolarity {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ImplPolarity {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                ImplPolarity::Positive => "Positive",
                ImplPolarity::Negative => "Negative",
                ImplPolarity::Reservation => "Reservation",
            })
    }
}Debug)]
209#[cfg_attr(
210    feature = "nightly",
211    derive(const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ImplPolarity {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { ImplPolarity::Positive }
                    1usize => { ImplPolarity::Negative }
                    2usize => { ImplPolarity::Reservation }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ImplPolarity`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ImplPolarity {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ImplPolarity::Positive => { 0usize }
                        ImplPolarity::Negative => { 1usize }
                        ImplPolarity::Reservation => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ImplPolarity::Positive => {}
                    ImplPolarity::Negative => {}
                    ImplPolarity::Reservation => {}
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for ImplPolarity {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    ImplPolarity::Positive => {}
                    ImplPolarity::Negative => {}
                    ImplPolarity::Reservation => {}
                }
            }
        }
    };HashStable_NoContext)
212)]
213pub enum ImplPolarity {
214    /// `impl Trait for Type`
215    Positive,
216    /// `impl !Trait for Type`
217    Negative,
218    /// `#[rustc_reservation_impl] impl Trait for Type`
219    ///
220    /// This is a "stability hack", not a real Rust feature.
221    /// See #64631 for details.
222    Reservation,
223}
224
225impl fmt::Display for ImplPolarity {
226    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227        match self {
228            Self::Positive => f.write_str("positive"),
229            Self::Negative => f.write_str("negative"),
230            Self::Reservation => f.write_str("reservation"),
231        }
232    }
233}
234
235impl ImplPolarity {
236    /// The polarity marker in front of the impl trait ref if applicable.
237    pub fn as_str(self) -> &'static str {
238        match self {
239            Self::Positive => "",
240            Self::Negative => "!",
241            Self::Reservation => "",
242        }
243    }
244}
245
246/// Polarity for a trait predicate.
247///
248/// May either be negative or positive.
249/// Distinguished from [`ImplPolarity`] since we never compute goals with
250/// "reservation" level.
251#[derive(#[automatically_derived]
impl ::core::clone::Clone for PredicatePolarity {
    #[inline]
    fn clone(&self) -> PredicatePolarity { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PredicatePolarity { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for PredicatePolarity {
    #[inline]
    fn eq(&self, other: &PredicatePolarity) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PredicatePolarity {
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for PredicatePolarity {
    #[inline]
    fn partial_cmp(&self, other: &PredicatePolarity)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for PredicatePolarity {
    #[inline]
    fn cmp(&self, other: &PredicatePolarity) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for PredicatePolarity {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PredicatePolarity {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                PredicatePolarity::Positive => "Positive",
                PredicatePolarity::Negative => "Negative",
            })
    }
}Debug)]
252#[cfg_attr(
253    feature = "nightly",
254    derive(const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for PredicatePolarity {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { PredicatePolarity::Positive }
                    1usize => { PredicatePolarity::Negative }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `PredicatePolarity`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for PredicatePolarity {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        PredicatePolarity::Positive => { 0usize }
                        PredicatePolarity::Negative => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    PredicatePolarity::Positive => {}
                    PredicatePolarity::Negative => {}
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for PredicatePolarity {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    PredicatePolarity::Positive => {}
                    PredicatePolarity::Negative => {}
                }
            }
        }
    };HashStable_NoContext)
255)]
256pub enum PredicatePolarity {
257    /// `Type: Trait`
258    Positive,
259    /// `Type: !Trait`
260    Negative,
261}
262
263impl PredicatePolarity {
264    /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`.
265    pub fn flip(&self) -> PredicatePolarity {
266        match self {
267            PredicatePolarity::Positive => PredicatePolarity::Negative,
268            PredicatePolarity::Negative => PredicatePolarity::Positive,
269        }
270    }
271}
272
273impl fmt::Display for PredicatePolarity {
274    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275        match self {
276            Self::Positive => f.write_str("positive"),
277            Self::Negative => f.write_str("negative"),
278        }
279    }
280}
281
282#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for ExistentialPredicate<I> where
    I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            ExistentialPredicate::Trait(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Trait");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            ExistentialPredicate::Projection(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Projection");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            ExistentialPredicate::AutoTrait(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "AutoTrait");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
283#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            ExistentialPredicate<I> where I: Interner,
            ExistentialTraitRef<I>: ::rustc_type_ir::TypeVisitable<I>,
            ExistentialProjection<I>: ::rustc_type_ir::TypeVisitable<I>,
            I::TraitId: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ExistentialPredicate::Trait(ref __binding_0) => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    ExistentialPredicate::Projection(ref __binding_0) => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                    ExistentialPredicate::AutoTrait(ref __binding_0) => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            ExistentialPredicate<I> where I: Interner,
            ExistentialTraitRef<I>: ::rustc_type_ir::TypeFoldable<I>,
            ExistentialProjection<I>: ::rustc_type_ir::TypeFoldable<I>,
            I::TraitId: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ExistentialPredicate::Trait(__binding_0) => {
                            ExistentialPredicate::Trait(::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        ExistentialPredicate::Projection(__binding_0) => {
                            ExistentialPredicate::Projection(::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                        ExistentialPredicate::AutoTrait(__binding_0) => {
                            ExistentialPredicate::AutoTrait(::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?)
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ExistentialPredicate::Trait(__binding_0) => {
                        ExistentialPredicate::Trait(::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    ExistentialPredicate::Projection(__binding_0) => {
                        ExistentialPredicate::Projection(::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                    ExistentialPredicate::AutoTrait(__binding_0) => {
                        ExistentialPredicate::AutoTrait(::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder))
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            ExistentialPredicate<I> where I: Interner, J: Interner,
            ExistentialTraitRef<I>: ::rustc_type_ir::lift::Lift<J, Lifted =
            ExistentialTraitRef<J>>,
            ExistentialProjection<I>: ::rustc_type_ir::lift::Lift<J, Lifted =
            ExistentialProjection<J>>,
            I::TraitId: ::rustc_type_ir::lift::Lift<J, Lifted = J::TraitId> {
            type Lifted = ExistentialPredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        ExistentialPredicate::Trait(__binding_0) => {
                            ExistentialPredicate::Trait(__binding_0.lift_to_interner(interner)?)
                        }
                        ExistentialPredicate::Projection(__binding_0) => {
                            ExistentialPredicate::Projection(__binding_0.lift_to_interner(interner)?)
                        }
                        ExistentialPredicate::AutoTrait(__binding_0) => {
                            ExistentialPredicate::AutoTrait(__binding_0.lift_to_interner(interner)?)
                        }
                    })
            }
        }
    };Lift_Generic)]
284#[cfg_attr(
285    feature = "nightly",
286    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ExistentialPredicate<I>
            where ExistentialTraitRef<I>: ::rustc_serialize::Decodable<__D>,
            ExistentialProjection<I>: ::rustc_serialize::Decodable<__D>,
            I::TraitId: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        ExistentialPredicate::Trait(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        ExistentialPredicate::Projection(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        ExistentialPredicate::AutoTrait(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ExistentialPredicate`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ExistentialPredicate<I>
            where ExistentialTraitRef<I>: ::rustc_serialize::Encodable<__E>,
            ExistentialProjection<I>: ::rustc_serialize::Encodable<__E>,
            I::TraitId: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ExistentialPredicate::Trait(ref __binding_0) => { 0usize }
                        ExistentialPredicate::Projection(ref __binding_0) => {
                            1usize
                        }
                        ExistentialPredicate::AutoTrait(ref __binding_0) => {
                            2usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ExistentialPredicate::Trait(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    ExistentialPredicate::Projection(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    ExistentialPredicate::AutoTrait(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            ExistentialPredicate<I> where
            ExistentialTraitRef<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            ExistentialProjection<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::TraitId: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    ExistentialPredicate::Trait(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExistentialPredicate::Projection(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    ExistentialPredicate::AutoTrait(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
287)]
288pub enum ExistentialPredicate<I: Interner> {
289    /// E.g., `Iterator`.
290    Trait(ExistentialTraitRef<I>),
291    /// E.g., `Iterator::Item = T`.
292    Projection(ExistentialProjection<I>),
293    /// E.g., `Send`.
294    AutoTrait(I::TraitId),
295}
296
297impl<I: Interner> Eq for ExistentialPredicate<I> {}
298
299impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
300    pub fn def_id(&self) -> I::DefId {
301        match self.skip_binder() {
302            ExistentialPredicate::Trait(tr) => tr.def_id.into(),
303            ExistentialPredicate::Projection(p) => p.def_id.into(),
304            ExistentialPredicate::AutoTrait(did) => did.into(),
305        }
306    }
307    /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
308    /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
309    /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
310    pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> I::Clause {
311        match self.skip_binder() {
312            ExistentialPredicate::Trait(tr) => self.rebind(tr).with_self_ty(cx, self_ty).upcast(cx),
313            ExistentialPredicate::Projection(p) => {
314                self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
315            }
316            ExistentialPredicate::AutoTrait(did) => {
317                let generics = cx.generics_of(did.into());
318                let trait_ref = if generics.count() == 1 {
319                    ty::TraitRef::new(cx, did, [self_ty])
320                } else {
321                    // If this is an ill-formed auto trait, then synthesize
322                    // new error args for the missing generics.
323                    let err_args =
324                        GenericArgs::extend_with_error(cx, did.into(), &[self_ty.into()]);
325                    ty::TraitRef::new_from_args(cx, did, err_args)
326                };
327                self.rebind(trait_ref).upcast(cx)
328            }
329        }
330    }
331}
332
333/// An existential reference to a trait, where `Self` is erased.
334///
335/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
336/// ```ignore (illustrative)
337/// exists T. T: Trait<'a, 'b, X, Y>
338/// ```
339/// The generic parameters don't include the erased `Self`, only trait
340/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
341#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for ExistentialTraitRef<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> bool {
        match (self, __other) {
            (ExistentialTraitRef {
                def_id: ref __field_def_id,
                args: ref __field_args,
                _use_existential_trait_ref_new_instead: ref __field__use_existential_trait_ref_new_instead
                }, ExistentialTraitRef {
                def_id: ref __other_field_def_id,
                args: ref __other_field_args,
                _use_existential_trait_ref_new_instead: ref __other_field__use_existential_trait_ref_new_instead
                }) =>
                true &&
                            ::core::cmp::PartialEq::eq(__field_def_id,
                                __other_field_def_id) &&
                        ::core::cmp::PartialEq::eq(__field_args, __other_field_args)
                    &&
                    ::core::cmp::PartialEq::eq(__field__use_existential_trait_ref_new_instead,
                        __other_field__use_existential_trait_ref_new_instead),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
342#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            ExistentialTraitRef<I> where I: Interner,
            I::TraitId: ::rustc_type_ir::TypeVisitable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ExistentialTraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_existential_trait_ref_new_instead: ref __binding_2 } =>
                        {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            ExistentialTraitRef<I> where I: Interner,
            I::TraitId: ::rustc_type_ir::TypeFoldable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ExistentialTraitRef {
                            def_id: __binding_0,
                            args: __binding_1,
                            _use_existential_trait_ref_new_instead: __binding_2 } => {
                            ExistentialTraitRef {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                args: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                _use_existential_trait_ref_new_instead: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ExistentialTraitRef {
                        def_id: __binding_0,
                        args: __binding_1,
                        _use_existential_trait_ref_new_instead: __binding_2 } => {
                        ExistentialTraitRef {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            args: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            _use_existential_trait_ref_new_instead: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            ExistentialTraitRef<I> where I: Interner, J: Interner,
            I::TraitId: ::rustc_type_ir::lift::Lift<J, Lifted = J::TraitId>,
            I::GenericArgs: ::rustc_type_ir::lift::Lift<J, Lifted =
            J::GenericArgs>, (): ::rustc_type_ir::lift::Lift<J, Lifted = ()> {
            type Lifted = ExistentialTraitRef<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        ExistentialTraitRef {
                            def_id: __binding_0,
                            args: __binding_1,
                            _use_existential_trait_ref_new_instead: __binding_2 } => {
                            ExistentialTraitRef {
                                def_id: __binding_0.lift_to_interner(interner)?,
                                args: __binding_1.lift_to_interner(interner)?,
                                _use_existential_trait_ref_new_instead: __binding_2.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
343#[cfg_attr(
344    feature = "nightly",
345    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ExistentialTraitRef<I> where
            I::TraitId: ::rustc_serialize::Decodable<__D>,
            I::GenericArgs: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                ExistentialTraitRef {
                    def_id: ::rustc_serialize::Decodable::decode(__decoder),
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    _use_existential_trait_ref_new_instead: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ExistentialTraitRef<I> where
            I::TraitId: ::rustc_serialize::Encodable<__E>,
            I::GenericArgs: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ExistentialTraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_existential_trait_ref_new_instead: ref __binding_2 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            ExistentialTraitRef<I> where
            I::TraitId: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::GenericArgs: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ExistentialTraitRef {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        _use_existential_trait_ref_new_instead: ref __binding_2 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
346)]
347pub struct ExistentialTraitRef<I: Interner> {
348    pub def_id: I::TraitId,
349    pub args: I::GenericArgs,
350    /// This field exists to prevent the creation of `ExistentialTraitRef` without
351    /// calling [`ExistentialTraitRef::new_from_args`].
352    _use_existential_trait_ref_new_instead: (),
353}
354
355impl<I: Interner> Eq for ExistentialTraitRef<I> {}
356
357impl<I: Interner> ExistentialTraitRef<I> {
358    pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
359        interner.debug_assert_existential_args_compatible(trait_def_id.into(), args);
360        Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
361    }
362
363    pub fn new(
364        interner: I,
365        trait_def_id: I::TraitId,
366        args: impl IntoIterator<Item: Into<I::GenericArg>>,
367    ) -> Self {
368        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
369        Self::new_from_args(interner, trait_def_id, args)
370    }
371
372    pub fn erase_self_ty(interner: I, trait_ref: TraitRef<I>) -> ExistentialTraitRef<I> {
373        // Assert there is a Self.
374        trait_ref.args.type_at(0);
375
376        ExistentialTraitRef {
377            def_id: trait_ref.def_id,
378            args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
379            _use_existential_trait_ref_new_instead: (),
380        }
381    }
382
383    /// Object types don't have a self type specified. Therefore, when
384    /// we convert the principal trait-ref into a normal trait-ref,
385    /// you must give *some* self type. A common choice is `mk_err()`
386    /// or some placeholder type.
387    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef<I> {
388        // otherwise the escaping vars would be captured by the binder
389        // debug_assert!(!self_ty.has_escaping_bound_vars());
390
391        TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
392    }
393}
394
395impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
396    pub fn def_id(&self) -> I::TraitId {
397        self.skip_binder().def_id
398    }
399
400    /// Object types don't have a self type specified. Therefore, when
401    /// we convert the principal trait-ref into a normal trait-ref,
402    /// you must give *some* self type. A common choice is `mk_err()`
403    /// or some placeholder type.
404    pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, TraitRef<I>> {
405        self.map_bound(|trait_ref| trait_ref.with_self_ty(cx, self_ty))
406    }
407}
408
409/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
410#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for ExistentialProjection<I> where
    I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            ExistentialProjection {
                def_id: ref __field_def_id,
                args: ref __field_args,
                term: ref __field_term,
                use_existential_projection_new_instead: ref __field_use_existential_projection_new_instead
                } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "ExistentialProjection");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::field(&mut __builder, "args",
                    __field_args);
                ::core::fmt::DebugStruct::field(&mut __builder, "term",
                    __field_term);
                ::core::fmt::DebugStruct::finish_non_exhaustive(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
411#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            ExistentialProjection<I> where I: Interner,
            I::DefId: ::rustc_type_ir::TypeVisitable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeVisitable<I>,
            I::Term: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ExistentialProjection {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        term: ref __binding_2,
                        use_existential_projection_new_instead: ref __binding_3 } =>
                        {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_3,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            ExistentialProjection<I> where I: Interner,
            I::DefId: ::rustc_type_ir::TypeFoldable<I>,
            I::GenericArgs: ::rustc_type_ir::TypeFoldable<I>,
            I::Term: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ExistentialProjection {
                            def_id: __binding_0,
                            args: __binding_1,
                            term: __binding_2,
                            use_existential_projection_new_instead: __binding_3 } => {
                            ExistentialProjection {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                args: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                term: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                                use_existential_projection_new_instead: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_3,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ExistentialProjection {
                        def_id: __binding_0,
                        args: __binding_1,
                        term: __binding_2,
                        use_existential_projection_new_instead: __binding_3 } => {
                        ExistentialProjection {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            args: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            term: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                            use_existential_projection_new_instead: ::rustc_type_ir::TypeFoldable::fold_with(__binding_3,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            ExistentialProjection<I> where I: Interner, J: Interner,
            I::DefId: ::rustc_type_ir::lift::Lift<J, Lifted = J::DefId>,
            I::GenericArgs: ::rustc_type_ir::lift::Lift<J, Lifted =
            J::GenericArgs>,
            I::Term: ::rustc_type_ir::lift::Lift<J, Lifted = J::Term>,
            (): ::rustc_type_ir::lift::Lift<J, Lifted = ()> {
            type Lifted = ExistentialProjection<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        ExistentialProjection {
                            def_id: __binding_0,
                            args: __binding_1,
                            term: __binding_2,
                            use_existential_projection_new_instead: __binding_3 } => {
                            ExistentialProjection {
                                def_id: __binding_0.lift_to_interner(interner)?,
                                args: __binding_1.lift_to_interner(interner)?,
                                term: __binding_2.lift_to_interner(interner)?,
                                use_existential_projection_new_instead: __binding_3.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
412#[cfg_attr(
413    feature = "nightly",
414    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ExistentialProjection<I>
            where I::DefId: ::rustc_serialize::Decodable<__D>,
            I::GenericArgs: ::rustc_serialize::Decodable<__D>,
            I::Term: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                ExistentialProjection {
                    def_id: ::rustc_serialize::Decodable::decode(__decoder),
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    term: ::rustc_serialize::Decodable::decode(__decoder),
                    use_existential_projection_new_instead: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ExistentialProjection<I>
            where I::DefId: ::rustc_serialize::Encodable<__E>,
            I::GenericArgs: ::rustc_serialize::Encodable<__E>,
            I::Term: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ExistentialProjection {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        term: ref __binding_2,
                        use_existential_projection_new_instead: ref __binding_3 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            ExistentialProjection<I> where
            I::DefId: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::GenericArgs: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::Term: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ExistentialProjection {
                        def_id: ref __binding_0,
                        args: ref __binding_1,
                        term: ref __binding_2,
                        use_existential_projection_new_instead: ref __binding_3 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
415)]
416pub struct ExistentialProjection<I: Interner> {
417    pub def_id: I::DefId,
418    pub args: I::GenericArgs,
419    pub term: I::Term,
420
421    /// This field exists to prevent the creation of `ExistentialProjection`
422    /// without using [`ExistentialProjection::new_from_args`].
423    #[derive_where(skip(Debug))]
424    use_existential_projection_new_instead: (),
425}
426
427impl<I: Interner> Eq for ExistentialProjection<I> {}
428
429impl<I: Interner> ExistentialProjection<I> {
430    pub fn new_from_args(
431        interner: I,
432        def_id: I::DefId,
433        args: I::GenericArgs,
434        term: I::Term,
435    ) -> ExistentialProjection<I> {
436        interner.debug_assert_existential_args_compatible(def_id, args);
437        Self { def_id, args, term, use_existential_projection_new_instead: () }
438    }
439
440    pub fn new(
441        interner: I,
442        def_id: I::DefId,
443        args: impl IntoIterator<Item: Into<I::GenericArg>>,
444        term: I::Term,
445    ) -> ExistentialProjection<I> {
446        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
447        Self::new_from_args(interner, def_id, args, term)
448    }
449
450    /// Extracts the underlying existential trait reference from this projection.
451    ///
452    /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
453    /// then this function would return an `exists T. T: Iterator` existential trait
454    /// reference.
455    pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
456        let def_id = interner.parent(self.def_id);
457        let args_count = interner.generics_of(def_id).count() - 1;
458        let args = interner.mk_args(&self.args.as_slice()[..args_count]);
459        ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args)
460    }
461
462    pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
463        // otherwise the escaping regions would be captured by the binders
464        if true {
    if !!self_ty.has_escaping_bound_vars() {
        ::core::panicking::panic("assertion failed: !self_ty.has_escaping_bound_vars()")
    };
};debug_assert!(!self_ty.has_escaping_bound_vars());
465
466        ProjectionPredicate {
467            projection_term: AliasTerm::new(
468                interner,
469                self.def_id,
470                [self_ty.into()].iter().chain(self.args.iter()),
471            ),
472            term: self.term,
473        }
474    }
475
476    pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
477        // Assert there is a Self.
478        projection_predicate.projection_term.args.type_at(0);
479
480        Self {
481            def_id: projection_predicate.projection_term.def_id,
482            args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
483            term: projection_predicate.term,
484            use_existential_projection_new_instead: (),
485        }
486    }
487}
488
489impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> {
490    pub fn with_self_ty(&self, cx: I, self_ty: I::Ty) -> ty::Binder<I, ProjectionPredicate<I>> {
491        self.map_bound(|p| p.with_self_ty(cx, self_ty))
492    }
493
494    pub fn item_def_id(&self) -> I::DefId {
495        self.skip_binder().def_id
496    }
497}
498
499#[derive(#[automatically_derived]
impl ::core::clone::Clone for AliasTermKind {
    #[inline]
    fn clone(&self) -> AliasTermKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AliasTermKind { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for AliasTermKind {
    #[inline]
    fn eq(&self, other: &AliasTermKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AliasTermKind {
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for AliasTermKind {
    #[inline]
    fn partial_cmp(&self, other: &AliasTermKind)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for AliasTermKind {
    #[inline]
    fn cmp(&self, other: &AliasTermKind) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for AliasTermKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AliasTermKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AliasTermKind::ProjectionTy => "ProjectionTy",
                AliasTermKind::InherentTy => "InherentTy",
                AliasTermKind::OpaqueTy => "OpaqueTy",
                AliasTermKind::FreeTy => "FreeTy",
                AliasTermKind::UnevaluatedConst => "UnevaluatedConst",
                AliasTermKind::ProjectionConst => "ProjectionConst",
                AliasTermKind::FreeConst => "FreeConst",
                AliasTermKind::InherentConst => "InherentConst",
            })
    }
}Debug)]
500#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for AliasTermKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AliasTermKind::ProjectionTy => { 0usize }
                        AliasTermKind::InherentTy => { 1usize }
                        AliasTermKind::OpaqueTy => { 2usize }
                        AliasTermKind::FreeTy => { 3usize }
                        AliasTermKind::UnevaluatedConst => { 4usize }
                        AliasTermKind::ProjectionConst => { 5usize }
                        AliasTermKind::FreeConst => { 6usize }
                        AliasTermKind::InherentConst => { 7usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AliasTermKind::ProjectionTy => {}
                    AliasTermKind::InherentTy => {}
                    AliasTermKind::OpaqueTy => {}
                    AliasTermKind::FreeTy => {}
                    AliasTermKind::UnevaluatedConst => {}
                    AliasTermKind::ProjectionConst => {}
                    AliasTermKind::FreeConst => {}
                    AliasTermKind::InherentConst => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for AliasTermKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { AliasTermKind::ProjectionTy }
                    1usize => { AliasTermKind::InherentTy }
                    2usize => { AliasTermKind::OpaqueTy }
                    3usize => { AliasTermKind::FreeTy }
                    4usize => { AliasTermKind::UnevaluatedConst }
                    5usize => { AliasTermKind::ProjectionConst }
                    6usize => { AliasTermKind::FreeConst }
                    7usize => { AliasTermKind::InherentConst }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AliasTermKind`, expected 0..8, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for AliasTermKind {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    AliasTermKind::ProjectionTy => {}
                    AliasTermKind::InherentTy => {}
                    AliasTermKind::OpaqueTy => {}
                    AliasTermKind::FreeTy => {}
                    AliasTermKind::UnevaluatedConst => {}
                    AliasTermKind::ProjectionConst => {}
                    AliasTermKind::FreeConst => {}
                    AliasTermKind::InherentConst => {}
                }
            }
        }
    };HashStable_NoContext))]
501pub enum AliasTermKind {
502    /// A projection `<Type as Trait>::AssocType`.
503    ///
504    /// Can get normalized away if monomorphic enough.
505    ProjectionTy,
506    /// An associated type in an inherent `impl`
507    InherentTy,
508    /// An opaque type (usually from `impl Trait` in type aliases or function return types)
509    ///
510    /// Can only be normalized away in PostAnalysis mode or its defining scope.
511    OpaqueTy,
512    /// A free type alias that actually checks its trait bounds.
513    ///
514    /// Currently only used if the type alias references opaque types.
515    /// Can always be normalized away.
516    FreeTy,
517
518    /// An unevaluated anonymous constants.
519    UnevaluatedConst,
520    /// An unevaluated const coming from an associated const.
521    ProjectionConst,
522    /// A top level const item not part of a trait or impl.
523    FreeConst,
524    /// An associated const in an inherent `impl`
525    InherentConst,
526}
527
528impl AliasTermKind {
529    pub fn descr(self) -> &'static str {
530        match self {
531            AliasTermKind::ProjectionTy => "associated type",
532            AliasTermKind::ProjectionConst => "associated const",
533            AliasTermKind::InherentTy => "inherent associated type",
534            AliasTermKind::InherentConst => "inherent associated const",
535            AliasTermKind::OpaqueTy => "opaque type",
536            AliasTermKind::FreeTy => "type alias",
537            AliasTermKind::FreeConst => "unevaluated constant",
538            AliasTermKind::UnevaluatedConst => "unevaluated constant",
539        }
540    }
541
542    pub fn is_type(self) -> bool {
543        match self {
544            AliasTermKind::ProjectionTy
545            | AliasTermKind::InherentTy
546            | AliasTermKind::OpaqueTy
547            | AliasTermKind::FreeTy => true,
548
549            AliasTermKind::UnevaluatedConst
550            | AliasTermKind::ProjectionConst
551            | AliasTermKind::InherentConst
552            | AliasTermKind::FreeConst => false,
553        }
554    }
555}
556
557impl From<ty::AliasTyKind> for AliasTermKind {
558    fn from(value: ty::AliasTyKind) -> Self {
559        match value {
560            ty::Projection => AliasTermKind::ProjectionTy,
561            ty::Opaque => AliasTermKind::OpaqueTy,
562            ty::Free => AliasTermKind::FreeTy,
563            ty::Inherent => AliasTermKind::InherentTy,
564        }
565    }
566}
567
568/// Represents the unprojected term of a projection goal.
569///
570/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
571/// * For an inherent projection, this would be `Ty::N<...>`.
572/// * For an opaque type, there is no explicit syntax.
573#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for AliasTerm<I> where I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            AliasTerm {
                args: ref __field_args,
                def_id: ref __field_def_id,
                _use_alias_term_new_instead: ref __field__use_alias_term_new_instead
                } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "AliasTerm");
                ::core::fmt::DebugStruct::field(&mut __builder, "args",
                    __field_args);
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish_non_exhaustive(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
574#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for AliasTerm<I>
            where I: Interner,
            I::GenericArgs: ::rustc_type_ir::TypeVisitable<I>,
            I::DefId: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    AliasTerm {
                        args: ref __binding_0,
                        def_id: ref __binding_1,
                        _use_alias_term_new_instead: ref __binding_2 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for AliasTerm<I>
            where I: Interner,
            I::GenericArgs: ::rustc_type_ir::TypeFoldable<I>,
            I::DefId: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        AliasTerm {
                            args: __binding_0,
                            def_id: __binding_1,
                            _use_alias_term_new_instead: __binding_2 } => {
                            AliasTerm {
                                args: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                _use_alias_term_new_instead: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    AliasTerm {
                        args: __binding_0,
                        def_id: __binding_1,
                        _use_alias_term_new_instead: __binding_2 } => {
                        AliasTerm {
                            args: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            _use_alias_term_new_instead: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for AliasTerm<I>
            where I: Interner, J: Interner,
            I::GenericArgs: ::rustc_type_ir::lift::Lift<J, Lifted =
            J::GenericArgs>,
            I::DefId: ::rustc_type_ir::lift::Lift<J, Lifted = J::DefId>,
            (): ::rustc_type_ir::lift::Lift<J, Lifted = ()> {
            type Lifted = AliasTerm<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        AliasTerm {
                            args: __binding_0,
                            def_id: __binding_1,
                            _use_alias_term_new_instead: __binding_2 } => {
                            AliasTerm {
                                args: __binding_0.lift_to_interner(interner)?,
                                def_id: __binding_1.lift_to_interner(interner)?,
                                _use_alias_term_new_instead: __binding_2.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
575#[cfg_attr(
576    feature = "nightly",
577    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for AliasTerm<I> where
            I::GenericArgs: ::rustc_serialize::Decodable<__D>,
            I::DefId: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                AliasTerm {
                    args: ::rustc_serialize::Decodable::decode(__decoder),
                    def_id: ::rustc_serialize::Decodable::decode(__decoder),
                    _use_alias_term_new_instead: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for AliasTerm<I> where
            I::GenericArgs: ::rustc_serialize::Encodable<__E>,
            I::DefId: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    AliasTerm {
                        args: ref __binding_0,
                        def_id: ref __binding_1,
                        _use_alias_term_new_instead: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            AliasTerm<I> where
            I::GenericArgs: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::DefId: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    AliasTerm {
                        args: ref __binding_0,
                        def_id: ref __binding_1,
                        _use_alias_term_new_instead: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
578)]
579pub struct AliasTerm<I: Interner> {
580    /// The parameters of the associated or opaque item.
581    ///
582    /// For a projection, these are the generic parameters for the trait and the
583    /// GAT parameters, if there are any.
584    ///
585    /// For an inherent projection, they consist of the self type and the GAT parameters,
586    /// if there are any.
587    ///
588    /// For RPIT the generic parameters are for the generics of the function,
589    /// while for TAIT it is used for the generic parameters of the alias.
590    pub args: I::GenericArgs,
591
592    /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
593    /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
594    /// this is an opaque.
595    ///
596    /// During codegen, `interner.type_of(def_id)` can be used to get the type of the
597    /// underlying type if the type is an opaque.
598    ///
599    /// Note that if this is an associated type, this is not the `DefId` of the
600    /// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
601    /// aka. `interner.parent(def_id)`.
602    pub def_id: I::DefId,
603
604    /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`].
605    #[derive_where(skip(Debug))]
606    _use_alias_term_new_instead: (),
607}
608
609impl<I: Interner> Eq for AliasTerm<I> {}
610
611impl<I: Interner> AliasTerm<I> {
612    pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
613        interner.debug_assert_args_compatible(def_id, args);
614        AliasTerm { def_id, args, _use_alias_term_new_instead: () }
615    }
616
617    pub fn new(
618        interner: I,
619        def_id: I::DefId,
620        args: impl IntoIterator<Item: Into<I::GenericArg>>,
621    ) -> AliasTerm<I> {
622        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
623        Self::new_from_args(interner, def_id, args)
624    }
625
626    pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
627        match self.kind(interner) {
628            AliasTermKind::ProjectionTy
629            | AliasTermKind::InherentTy
630            | AliasTermKind::OpaqueTy
631            | AliasTermKind::FreeTy => {}
632            AliasTermKind::InherentConst
633            | AliasTermKind::FreeConst
634            | AliasTermKind::UnevaluatedConst
635            | AliasTermKind::ProjectionConst => {
636                {
    ::core::panicking::panic_fmt(format_args!("Cannot turn `UnevaluatedConst` into `AliasTy`"));
}panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
637            }
638        }
639        ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
640    }
641
642    pub fn kind(self, interner: I) -> AliasTermKind {
643        interner.alias_term_kind(self)
644    }
645
646    pub fn to_term(self, interner: I) -> I::Term {
647        match self.kind(interner) {
648            AliasTermKind::ProjectionTy => Ty::new_alias(
649                interner,
650                ty::AliasTyKind::Projection,
651                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
652            )
653            .into(),
654            AliasTermKind::InherentTy => Ty::new_alias(
655                interner,
656                ty::AliasTyKind::Inherent,
657                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
658            )
659            .into(),
660            AliasTermKind::OpaqueTy => Ty::new_alias(
661                interner,
662                ty::AliasTyKind::Opaque,
663                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
664            )
665            .into(),
666            AliasTermKind::FreeTy => Ty::new_alias(
667                interner,
668                ty::AliasTyKind::Free,
669                ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
670            )
671            .into(),
672            AliasTermKind::FreeConst
673            | AliasTermKind::InherentConst
674            | AliasTermKind::UnevaluatedConst
675            | AliasTermKind::ProjectionConst => I::Const::new_unevaluated(
676                interner,
677                ty::UnevaluatedConst::new(self.def_id.try_into().unwrap(), self.args),
678            )
679            .into(),
680        }
681    }
682}
683
684/// The following methods work only with (trait) associated term projections.
685impl<I: Interner> AliasTerm<I> {
686    pub fn self_ty(self) -> I::Ty {
687        self.args.type_at(0)
688    }
689
690    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
691        AliasTerm::new(
692            interner,
693            self.def_id,
694            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
695        )
696    }
697
698    pub fn trait_def_id(self, interner: I) -> I::TraitId {
699        if !#[allow(non_exhaustive_omitted_patterns)] match self.kind(interner) {
            AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst =>
                true,
            _ => false,
        } {
    { ::core::panicking::panic_fmt(format_args!("expected a projection")); }
};assert!(
700            matches!(
701                self.kind(interner),
702                AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
703            ),
704            "expected a projection"
705        );
706        interner.parent(self.def_id).try_into().unwrap()
707    }
708
709    /// Extracts the underlying trait reference and own args from this projection.
710    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
711    /// then this function would return a `T: StreamingIterator` trait reference and
712    /// `['a]` as the own args.
713    pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
714        interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
715    }
716
717    /// Extracts the underlying trait reference from this projection.
718    /// For example, if this is a projection of `<T as Iterator>::Item`,
719    /// then this function would return a `T: Iterator` trait reference.
720    ///
721    /// WARNING: This will drop the args for generic associated types
722    /// consider calling [Self::trait_ref_and_own_args] to get those
723    /// as well.
724    pub fn trait_ref(self, interner: I) -> TraitRef<I> {
725        self.trait_ref_and_own_args(interner).0
726    }
727
728    /// Extract the own args from this projection.
729    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
730    /// then this function would return the slice `['a]` as the own args.
731    pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
732        self.trait_ref_and_own_args(interner).1
733    }
734}
735
736/// The following methods work only with inherent associated term projections.
737impl<I: Interner> AliasTerm<I> {
738    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
739    ///
740    /// Does the following transformation:
741    ///
742    /// ```text
743    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
744    ///
745    ///     I_i impl args
746    ///     P_j GAT args
747    /// ```
748    pub fn rebase_inherent_args_onto_impl(
749        self,
750        impl_args: I::GenericArgs,
751        interner: I,
752    ) -> I::GenericArgs {
753        if true {
    if !#[allow(non_exhaustive_omitted_patterns)] match self.kind(interner) {
                AliasTermKind::InherentTy | AliasTermKind::InherentConst =>
                    true,
                _ => false,
            } {
        ::core::panicking::panic("assertion failed: matches!(self.kind(interner), AliasTermKind::InherentTy |\n    AliasTermKind::InherentConst)")
    };
};debug_assert!(matches!(
754            self.kind(interner),
755            AliasTermKind::InherentTy | AliasTermKind::InherentConst
756        ));
757        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
758    }
759}
760
761impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
762    fn from(ty: ty::AliasTy<I>) -> Self {
763        AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
764    }
765}
766
767impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
768    fn from(ct: ty::UnevaluatedConst<I>) -> Self {
769        AliasTerm { args: ct.args, def_id: ct.def.into(), _use_alias_term_new_instead: () }
770    }
771}
772
773/// This kind of predicate has no *direct* correspondent in the
774/// syntax, but it roughly corresponds to the syntactic forms:
775///
776/// 1. `T: TraitRef<..., Item = Type>`
777/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
778///
779/// In particular, form #1 is "desugared" to the combination of a
780/// normal trait predicate (`T: TraitRef<...>`) and one of these
781/// predicates. Form #2 is a broader form in that it also permits
782/// equality between arbitrary types. Processing an instance of
783/// Form #2 eventually yields one of these `ProjectionPredicate`
784/// instances to normalize the LHS.
785#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for ProjectionPredicate<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> bool {
        match (self, __other) {
            (ProjectionPredicate {
                projection_term: ref __field_projection_term,
                term: ref __field_term }, ProjectionPredicate {
                projection_term: ref __other_field_projection_term,
                term: ref __other_field_term }) =>
                true &&
                        ::core::cmp::PartialEq::eq(__field_projection_term,
                            __other_field_projection_term) &&
                    ::core::cmp::PartialEq::eq(__field_term,
                        __other_field_term),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
786#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            ProjectionPredicate<I> where I: Interner,
            AliasTerm<I>: ::rustc_type_ir::TypeVisitable<I>,
            I::Term: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    ProjectionPredicate {
                        projection_term: ref __binding_0, term: ref __binding_1 } =>
                        {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            ProjectionPredicate<I> where I: Interner,
            AliasTerm<I>: ::rustc_type_ir::TypeFoldable<I>,
            I::Term: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        ProjectionPredicate {
                            projection_term: __binding_0, term: __binding_1 } => {
                            ProjectionPredicate {
                                projection_term: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                term: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    ProjectionPredicate {
                        projection_term: __binding_0, term: __binding_1 } => {
                        ProjectionPredicate {
                            projection_term: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            term: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            ProjectionPredicate<I> where I: Interner, J: Interner,
            AliasTerm<I>: ::rustc_type_ir::lift::Lift<J, Lifted =
            AliasTerm<J>>,
            I::Term: ::rustc_type_ir::lift::Lift<J, Lifted = J::Term> {
            type Lifted = ProjectionPredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        ProjectionPredicate {
                            projection_term: __binding_0, term: __binding_1 } => {
                            ProjectionPredicate {
                                projection_term: __binding_0.lift_to_interner(interner)?,
                                term: __binding_1.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
787#[cfg_attr(
788    feature = "nightly",
789    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ProjectionPredicate<I> where
            AliasTerm<I>: ::rustc_serialize::Decodable<__D>,
            I::Term: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                ProjectionPredicate {
                    projection_term: ::rustc_serialize::Decodable::decode(__decoder),
                    term: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ProjectionPredicate<I> where
            AliasTerm<I>: ::rustc_serialize::Encodable<__E>,
            I::Term: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ProjectionPredicate {
                        projection_term: ref __binding_0, term: ref __binding_1 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            ProjectionPredicate<I> where
            AliasTerm<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::Term: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ProjectionPredicate {
                        projection_term: ref __binding_0, term: ref __binding_1 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
790)]
791pub struct ProjectionPredicate<I: Interner> {
792    pub projection_term: AliasTerm<I>,
793    pub term: I::Term,
794}
795
796impl<I: Interner> Eq for ProjectionPredicate<I> {}
797
798impl<I: Interner> ProjectionPredicate<I> {
799    pub fn self_ty(self) -> I::Ty {
800        self.projection_term.self_ty()
801    }
802
803    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
804        Self {
805            projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
806            ..self
807        }
808    }
809
810    pub fn trait_def_id(self, interner: I) -> I::TraitId {
811        self.projection_term.trait_def_id(interner)
812    }
813
814    pub fn def_id(self) -> I::DefId {
815        self.projection_term.def_id
816    }
817}
818
819impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
820    /// Returns the `DefId` of the trait of the associated item being projected.
821    #[inline]
822    pub fn trait_def_id(&self, cx: I) -> I::TraitId {
823        self.skip_binder().projection_term.trait_def_id(cx)
824    }
825
826    pub fn term(&self) -> ty::Binder<I, I::Term> {
827        self.map_bound(|predicate| predicate.term)
828    }
829
830    /// The `DefId` of the `TraitItem` for the associated type.
831    ///
832    /// Note that this is not the `DefId` of the `TraitRef` containing this
833    /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
834    pub fn item_def_id(&self) -> I::DefId {
835        // Ok to skip binder since trait `DefId` does not care about regions.
836        self.skip_binder().projection_term.def_id
837    }
838}
839
840impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
841    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842        f.write_fmt(format_args!("ProjectionPredicate({0:?}, {1:?})",
        self.projection_term, self.term))write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term)
843    }
844}
845
846/// Used by the new solver to normalize an alias. This always expects the `term` to
847/// be an unconstrained inference variable which is used as the output.
848#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for NormalizesTo<I> where I: Interner
    {
    #[inline]
    fn eq(&self, __other: &Self) -> bool {
        match (self, __other) {
            (NormalizesTo { alias: ref __field_alias, term: ref __field_term
                }, NormalizesTo {
                alias: ref __other_field_alias, term: ref __other_field_term
                }) =>
                true &&
                        ::core::cmp::PartialEq::eq(__field_alias,
                            __other_field_alias) &&
                    ::core::cmp::PartialEq::eq(__field_term,
                        __other_field_term),
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
849#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            NormalizesTo<I> where I: Interner,
            AliasTerm<I>: ::rustc_type_ir::TypeVisitable<I>,
            I::Term: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    NormalizesTo { alias: ref __binding_0, term: ref __binding_1
                        } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for NormalizesTo<I>
            where I: Interner, AliasTerm<I>: ::rustc_type_ir::TypeFoldable<I>,
            I::Term: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        NormalizesTo { alias: __binding_0, term: __binding_1 } => {
                            NormalizesTo {
                                alias: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                term: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    NormalizesTo { alias: __binding_0, term: __binding_1 } => {
                        NormalizesTo {
                            alias: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            term: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            NormalizesTo<I> where I: Interner, J: Interner,
            AliasTerm<I>: ::rustc_type_ir::lift::Lift<J, Lifted =
            AliasTerm<J>>,
            I::Term: ::rustc_type_ir::lift::Lift<J, Lifted = J::Term> {
            type Lifted = NormalizesTo<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        NormalizesTo { alias: __binding_0, term: __binding_1 } => {
                            NormalizesTo {
                                alias: __binding_0.lift_to_interner(interner)?,
                                term: __binding_1.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
850#[cfg_attr(
851    feature = "nightly",
852    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for NormalizesTo<I> where
            AliasTerm<I>: ::rustc_serialize::Decodable<__D>,
            I::Term: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                NormalizesTo {
                    alias: ::rustc_serialize::Decodable::decode(__decoder),
                    term: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for NormalizesTo<I> where
            AliasTerm<I>: ::rustc_serialize::Encodable<__E>,
            I::Term: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    NormalizesTo { alias: ref __binding_0, term: ref __binding_1
                        } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            NormalizesTo<I> where
            AliasTerm<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>,
            I::Term: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    NormalizesTo { alias: ref __binding_0, term: ref __binding_1
                        } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
853)]
854pub struct NormalizesTo<I: Interner> {
855    pub alias: AliasTerm<I>,
856    pub term: I::Term,
857}
858
859impl<I: Interner> Eq for NormalizesTo<I> {}
860
861impl<I: Interner> NormalizesTo<I> {
862    pub fn self_ty(self) -> I::Ty {
863        self.alias.self_ty()
864    }
865
866    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
867        Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
868    }
869
870    pub fn trait_def_id(self, interner: I) -> I::TraitId {
871        self.alias.trait_def_id(interner)
872    }
873
874    pub fn def_id(self) -> I::DefId {
875        self.alias.def_id
876    }
877}
878
879impl<I: Interner> fmt::Debug for NormalizesTo<I> {
880    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
881        f.write_fmt(format_args!("NormalizesTo({0:?}, {1:?})", self.alias, self.term))write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term)
882    }
883}
884
885#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for HostEffectPredicate<I> where
    I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            HostEffectPredicate {
                trait_ref: ref __field_trait_ref,
                constness: ref __field_constness } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "HostEffectPredicate");
                ::core::fmt::DebugStruct::field(&mut __builder, "trait_ref",
                    __field_trait_ref);
                ::core::fmt::DebugStruct::field(&mut __builder, "constness",
                    __field_constness);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
886#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            HostEffectPredicate<I> where I: Interner,
            ty::TraitRef<I>: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    HostEffectPredicate {
                        trait_ref: ref __binding_0, constness: ref __binding_1 } =>
                        {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            HostEffectPredicate<I> where I: Interner,
            ty::TraitRef<I>: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        HostEffectPredicate {
                            trait_ref: __binding_0, constness: __binding_1 } => {
                            HostEffectPredicate {
                                trait_ref: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                constness: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    HostEffectPredicate {
                        trait_ref: __binding_0, constness: __binding_1 } => {
                        HostEffectPredicate {
                            trait_ref: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            constness: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            HostEffectPredicate<I> where I: Interner, J: Interner,
            ty::TraitRef<I>: ::rustc_type_ir::lift::Lift<J, Lifted =
            ty::TraitRef<J>>,
            BoundConstness: ::rustc_type_ir::lift::Lift<J, Lifted =
            BoundConstness> {
            type Lifted = HostEffectPredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        HostEffectPredicate {
                            trait_ref: __binding_0, constness: __binding_1 } => {
                            HostEffectPredicate {
                                trait_ref: __binding_0.lift_to_interner(interner)?,
                                constness: __binding_1.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
887#[cfg_attr(
888    feature = "nightly",
889    derive(const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for HostEffectPredicate<I> where
            ty::TraitRef<I>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    HostEffectPredicate {
                        trait_ref: ref __binding_0, constness: ref __binding_1 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for HostEffectPredicate<I> where
            ty::TraitRef<I>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                HostEffectPredicate {
                    trait_ref: ::rustc_serialize::Decodable::decode(__decoder),
                    constness: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            HostEffectPredicate<I> where
            ty::TraitRef<I>: ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    HostEffectPredicate {
                        trait_ref: ref __binding_0, constness: ref __binding_1 } =>
                        {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
890)]
891pub struct HostEffectPredicate<I: Interner> {
892    pub trait_ref: ty::TraitRef<I>,
893    pub constness: BoundConstness,
894}
895
896impl<I: Interner> Eq for HostEffectPredicate<I> {}
897
898impl<I: Interner> HostEffectPredicate<I> {
899    pub fn self_ty(self) -> I::Ty {
900        self.trait_ref.self_ty()
901    }
902
903    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
904        Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
905    }
906
907    pub fn def_id(self) -> I::TraitId {
908        self.trait_ref.def_id
909    }
910}
911
912impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
913    pub fn def_id(self) -> I::TraitId {
914        // Ok to skip binder since trait `DefId` does not care about regions.
915        self.skip_binder().def_id()
916    }
917
918    pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
919        self.map_bound(|trait_ref| trait_ref.self_ty())
920    }
921
922    #[inline]
923    pub fn constness(self) -> BoundConstness {
924        self.skip_binder().constness
925    }
926}
927
928/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
929/// whether the `a` type is the type that we should label as "expected" when
930/// presenting user diagnostics.
931#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for SubtypePredicate<I> where I: Interner
    {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            SubtypePredicate {
                a_is_expected: ref __field_a_is_expected,
                a: ref __field_a,
                b: ref __field_b } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "SubtypePredicate");
                ::core::fmt::DebugStruct::field(&mut __builder,
                    "a_is_expected", __field_a_is_expected);
                ::core::fmt::DebugStruct::field(&mut __builder, "a",
                    __field_a);
                ::core::fmt::DebugStruct::field(&mut __builder, "b",
                    __field_b);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
932#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            SubtypePredicate<I> where I: Interner,
            I::Ty: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    SubtypePredicate {
                        a_is_expected: ref __binding_0,
                        a: ref __binding_1,
                        b: ref __binding_2 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_2,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            SubtypePredicate<I> where I: Interner,
            I::Ty: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        SubtypePredicate {
                            a_is_expected: __binding_0, a: __binding_1, b: __binding_2 }
                            => {
                            SubtypePredicate {
                                a_is_expected: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                a: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                                b: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_2,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    SubtypePredicate {
                        a_is_expected: __binding_0, a: __binding_1, b: __binding_2 }
                        => {
                        SubtypePredicate {
                            a_is_expected: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            a: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                            b: ::rustc_type_ir::TypeFoldable::fold_with(__binding_2,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            SubtypePredicate<I> where I: Interner, J: Interner,
            bool: ::rustc_type_ir::lift::Lift<J, Lifted = bool>,
            I::Ty: ::rustc_type_ir::lift::Lift<J, Lifted = J::Ty>,
            I::Ty: ::rustc_type_ir::lift::Lift<J, Lifted = J::Ty> {
            type Lifted = SubtypePredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        SubtypePredicate {
                            a_is_expected: __binding_0, a: __binding_1, b: __binding_2 }
                            => {
                            SubtypePredicate {
                                a_is_expected: __binding_0.lift_to_interner(interner)?,
                                a: __binding_1.lift_to_interner(interner)?,
                                b: __binding_2.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
933#[cfg_attr(
934    feature = "nightly",
935    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for SubtypePredicate<I> where
            I::Ty: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                SubtypePredicate {
                    a_is_expected: ::rustc_serialize::Decodable::decode(__decoder),
                    a: ::rustc_serialize::Decodable::decode(__decoder),
                    b: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for SubtypePredicate<I> where
            I::Ty: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    SubtypePredicate {
                        a_is_expected: ref __binding_0,
                        a: ref __binding_1,
                        b: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            SubtypePredicate<I> where
            I::Ty: ::rustc_data_structures::stable_hasher::HashStable<__CTX> {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    SubtypePredicate {
                        a_is_expected: ref __binding_0,
                        a: ref __binding_1,
                        b: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
936)]
937pub struct SubtypePredicate<I: Interner> {
938    pub a_is_expected: bool,
939    pub a: I::Ty,
940    pub b: I::Ty,
941}
942
943impl<I: Interner> Eq for SubtypePredicate<I> {}
944
945/// Encodes that we have to coerce *from* the `a` type to the `b` type.
946#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for CoercePredicate<I> where I: Interner
    {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CoercePredicate { a: ref __field_a, b: ref __field_b } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "CoercePredicate");
                ::core::fmt::DebugStruct::field(&mut __builder, "a",
                    __field_a);
                ::core::fmt::DebugStruct::field(&mut __builder, "b",
                    __field_b);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
947#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            CoercePredicate<I> where I: Interner,
            I::Ty: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    CoercePredicate { a: ref __binding_0, b: ref __binding_1 }
                        => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_1,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            CoercePredicate<I> where I: Interner,
            I::Ty: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        CoercePredicate { a: __binding_0, b: __binding_1 } => {
                            CoercePredicate {
                                a: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                                b: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_1,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    CoercePredicate { a: __binding_0, b: __binding_1 } => {
                        CoercePredicate {
                            a: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                            b: ::rustc_type_ir::TypeFoldable::fold_with(__binding_1,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            CoercePredicate<I> where I: Interner, J: Interner,
            I::Ty: ::rustc_type_ir::lift::Lift<J, Lifted = J::Ty>,
            I::Ty: ::rustc_type_ir::lift::Lift<J, Lifted = J::Ty> {
            type Lifted = CoercePredicate<J>;
            fn lift_to_interner(self, interner: J) -> Option<Self::Lifted> {
                Some(match self {
                        CoercePredicate { a: __binding_0, b: __binding_1 } => {
                            CoercePredicate {
                                a: __binding_0.lift_to_interner(interner)?,
                                b: __binding_1.lift_to_interner(interner)?,
                            }
                        }
                    })
            }
        }
    };Lift_Generic)]
948#[cfg_attr(
949    feature = "nightly",
950    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for CoercePredicate<I> where
            I::Ty: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                CoercePredicate {
                    a: ::rustc_serialize::Decodable::decode(__decoder),
                    b: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for CoercePredicate<I> where
            I::Ty: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    CoercePredicate { a: ref __binding_0, b: ref __binding_1 }
                        => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __CTX>
            ::rustc_data_structures::stable_hasher::HashStable<__CTX> for
            CoercePredicate<I> where
            I::Ty: ::rustc_data_structures::stable_hasher::HashStable<__CTX> {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    CoercePredicate { a: ref __binding_0, b: ref __binding_1 }
                        => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_NoContext)
951)]
952pub struct CoercePredicate<I: Interner> {
953    pub a: I::Ty,
954    pub b: I::Ty,
955}
956
957impl<I: Interner> Eq for CoercePredicate<I> {}
958
959#[derive(#[automatically_derived]
impl ::core::clone::Clone for BoundConstness {
    #[inline]
    fn clone(&self) -> BoundConstness { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BoundConstness { }Copy, #[automatically_derived]
impl ::core::hash::Hash for BoundConstness {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for BoundConstness {
    #[inline]
    fn eq(&self, other: &BoundConstness) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BoundConstness {
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for BoundConstness {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                BoundConstness::Const => "Const",
                BoundConstness::Maybe => "Maybe",
            })
    }
}Debug)]
960#[cfg_attr(
961    feature = "nightly",
962    derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for BoundConstness {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        BoundConstness::Const => { 0usize }
                        BoundConstness::Maybe => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    BoundConstness::Const => {}
                    BoundConstness::Maybe => {}
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for BoundConstness {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { BoundConstness::Const }
                    1usize => { BoundConstness::Maybe }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `BoundConstness`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for BoundConstness {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    BoundConstness::Const => {}
                    BoundConstness::Maybe => {}
                }
            }
        }
    };HashStable_NoContext)
963)]
964pub enum BoundConstness {
965    /// `Type: const Trait`
966    ///
967    /// A bound is required to be unconditionally const, even in a runtime function.
968    Const,
969    /// `Type: [const] Trait`
970    ///
971    /// Requires resolving to const only when we are in a const context.
972    Maybe,
973}
974
975impl BoundConstness {
976    pub fn satisfies(self, goal: BoundConstness) -> bool {
977        match (self, goal) {
978            (BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
979            (BoundConstness::Maybe, BoundConstness::Maybe) => true,
980            (BoundConstness::Maybe, BoundConstness::Const) => false,
981        }
982    }
983
984    pub fn as_str(self) -> &'static str {
985        match self {
986            Self::Const => "const",
987            Self::Maybe => "[const]",
988        }
989    }
990}
991
992impl fmt::Display for BoundConstness {
993    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
994        match self {
995            Self::Const => f.write_str("const"),
996            Self::Maybe => f.write_str("[const]"),
997        }
998    }
999}