Skip to main content

rustc_type_ir/
term_kind.rs

1use derive_where::derive_where;
2#[cfg(feature = "nightly")]
3use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
4use rustc_type_ir_macros::{
5    GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
6};
7
8use crate::inherent::*;
9use crate::{self as ty, AliasTerm, Interner};
10
11#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for TermKind<I> where I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            TermKind::Ty(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Ty");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            TermKind::Const(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Const");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
12#[derive(GenericTypeVisitable)]
13#[cfg_attr(
14    feature = "nightly",
15    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for TermKind<I> where
            I::Ty: ::rustc_serialize::Decodable<__D>,
            I::Const: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        TermKind::Ty(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        TermKind::Const(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `TermKind`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for TermKind<I> where
            I::Ty: ::rustc_serialize::Encodable<__E>,
            I::Const: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        TermKind::Ty(ref __binding_0) => { 0usize }
                        TermKind::Const(ref __binding_0) => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    TermKind::Ty(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    TermKind::Const(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            TermKind<I> where
            I::Ty: ::rustc_data_structures::stable_hash::StableHash,
            I::Const: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    TermKind::Ty(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    TermKind::Const(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
16)]
17pub enum TermKind<I: Interner> {
18    Ty(I::Ty),
19    Const(I::Const),
20}
21
22impl<I: Interner> Eq for TermKind<I> {}
23
24#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for AliasTermKind<I> where I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            AliasTermKind::ProjectionTy { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "ProjectionTy");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::InherentTy { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "InherentTy");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::OpaqueTy { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "OpaqueTy");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::FreeTy { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "FreeTy");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::AnonConst { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "AnonConst");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::ProjectionConst { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "ProjectionConst");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::FreeConst { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "FreeConst");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            AliasTermKind::InherentConst { def_id: ref __field_def_id } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "InherentConst");
                ::core::fmt::DebugStruct::field(&mut __builder, "def_id",
                    __field_def_id);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
25#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            AliasTermKind<I> where I: Interner,
            I::TraitAssocTyId: ::rustc_type_ir::TypeVisitable<I>,
            I::InherentAssocTyId: ::rustc_type_ir::TypeVisitable<I>,
            I::OpaqueTyId: ::rustc_type_ir::TypeVisitable<I>,
            I::FreeTyAliasId: ::rustc_type_ir::TypeVisitable<I>,
            I::AnonConstId: ::rustc_type_ir::TypeVisitable<I>,
            I::TraitAssocConstId: ::rustc_type_ir::TypeVisitable<I>,
            I::FreeConstAliasId: ::rustc_type_ir::TypeVisitable<I>,
            I::InherentAssocConstId: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    AliasTermKind::ProjectionTy { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::InherentTy { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::OpaqueTy { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::FreeTy { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::AnonConst { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::ProjectionConst { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::FreeConst { def_id: 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);
                                }
                            }
                        }
                    }
                    AliasTermKind::InherentConst { def_id: 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, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            AliasTermKind<I> where I: Interner,
            I::TraitAssocTyId: ::rustc_type_ir::TypeFoldable<I>,
            I::InherentAssocTyId: ::rustc_type_ir::TypeFoldable<I>,
            I::OpaqueTyId: ::rustc_type_ir::TypeFoldable<I>,
            I::FreeTyAliasId: ::rustc_type_ir::TypeFoldable<I>,
            I::AnonConstId: ::rustc_type_ir::TypeFoldable<I>,
            I::TraitAssocConstId: ::rustc_type_ir::TypeFoldable<I>,
            I::FreeConstAliasId: ::rustc_type_ir::TypeFoldable<I>,
            I::InherentAssocConstId: ::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 {
                        AliasTermKind::ProjectionTy { def_id: __binding_0 } => {
                            AliasTermKind::ProjectionTy {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::InherentTy { def_id: __binding_0 } => {
                            AliasTermKind::InherentTy {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::OpaqueTy { def_id: __binding_0 } => {
                            AliasTermKind::OpaqueTy {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::FreeTy { def_id: __binding_0 } => {
                            AliasTermKind::FreeTy {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::AnonConst { def_id: __binding_0 } => {
                            AliasTermKind::AnonConst {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::ProjectionConst { def_id: __binding_0 } => {
                            AliasTermKind::ProjectionConst {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::FreeConst { def_id: __binding_0 } => {
                            AliasTermKind::FreeConst {
                                def_id: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                        AliasTermKind::InherentConst { def_id: __binding_0 } => {
                            AliasTermKind::InherentConst {
                                def_id: ::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 {
                    AliasTermKind::ProjectionTy { def_id: __binding_0 } => {
                        AliasTermKind::ProjectionTy {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::InherentTy { def_id: __binding_0 } => {
                        AliasTermKind::InherentTy {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::OpaqueTy { def_id: __binding_0 } => {
                        AliasTermKind::OpaqueTy {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::FreeTy { def_id: __binding_0 } => {
                        AliasTermKind::FreeTy {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::AnonConst { def_id: __binding_0 } => {
                        AliasTermKind::AnonConst {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::ProjectionConst { def_id: __binding_0 } => {
                        AliasTermKind::ProjectionConst {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::FreeConst { def_id: __binding_0 } => {
                        AliasTermKind::FreeConst {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                    AliasTermKind::InherentConst { def_id: __binding_0 } => {
                        AliasTermKind::InherentConst {
                            def_id: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            AliasTermKind<I> where J: Interner,
            I: ::rustc_type_ir::LiftInto<J> {
            type Lifted = AliasTermKind<J>;
            fn lift_to_interner(self, interner: J) -> Self::Lifted {
                match self {
                    AliasTermKind::ProjectionTy { def_id: __binding_0 } => {
                        AliasTermKind::ProjectionTy {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::InherentTy { def_id: __binding_0 } => {
                        AliasTermKind::InherentTy {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::OpaqueTy { def_id: __binding_0 } => {
                        AliasTermKind::OpaqueTy {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::FreeTy { def_id: __binding_0 } => {
                        AliasTermKind::FreeTy {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::AnonConst { def_id: __binding_0 } => {
                        AliasTermKind::AnonConst {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::ProjectionConst { def_id: __binding_0 } => {
                        AliasTermKind::ProjectionConst {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::FreeConst { def_id: __binding_0 } => {
                        AliasTermKind::FreeConst {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                    AliasTermKind::InherentConst { def_id: __binding_0 } => {
                        AliasTermKind::InherentConst {
                            def_id: __binding_0.lift_to_interner(interner),
                        }
                    }
                }
            }
        }
    };Lift_Generic, GenericTypeVisitable)]
26#[cfg_attr(
27    feature = "nightly",
28    derive(const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for AliasTermKind<I> where
            I::TraitAssocTyId: ::rustc_serialize::Encodable<__E>,
            I::InherentAssocTyId: ::rustc_serialize::Encodable<__E>,
            I::OpaqueTyId: ::rustc_serialize::Encodable<__E>,
            I::FreeTyAliasId: ::rustc_serialize::Encodable<__E>,
            I::AnonConstId: ::rustc_serialize::Encodable<__E>,
            I::TraitAssocConstId: ::rustc_serialize::Encodable<__E>,
            I::FreeConstAliasId: ::rustc_serialize::Encodable<__E>,
            I::InherentAssocConstId: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AliasTermKind::ProjectionTy { def_id: ref __binding_0 } => {
                            0usize
                        }
                        AliasTermKind::InherentTy { def_id: ref __binding_0 } => {
                            1usize
                        }
                        AliasTermKind::OpaqueTy { def_id: ref __binding_0 } => {
                            2usize
                        }
                        AliasTermKind::FreeTy { def_id: ref __binding_0 } => {
                            3usize
                        }
                        AliasTermKind::AnonConst { def_id: ref __binding_0 } => {
                            4usize
                        }
                        AliasTermKind::ProjectionConst { def_id: ref __binding_0 }
                            => {
                            5usize
                        }
                        AliasTermKind::FreeConst { def_id: ref __binding_0 } => {
                            6usize
                        }
                        AliasTermKind::InherentConst { def_id: ref __binding_0 } =>
                            {
                            7usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AliasTermKind::ProjectionTy { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::InherentTy { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::OpaqueTy { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::FreeTy { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::AnonConst { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::ProjectionConst { def_id: ref __binding_0 }
                        => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::FreeConst { def_id: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AliasTermKind::InherentConst { def_id: ref __binding_0 } =>
                        {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for AliasTermKind<I> where
            I::TraitAssocTyId: ::rustc_serialize::Decodable<__D>,
            I::InherentAssocTyId: ::rustc_serialize::Decodable<__D>,
            I::OpaqueTyId: ::rustc_serialize::Decodable<__D>,
            I::FreeTyAliasId: ::rustc_serialize::Decodable<__D>,
            I::AnonConstId: ::rustc_serialize::Decodable<__D>,
            I::TraitAssocConstId: ::rustc_serialize::Decodable<__D>,
            I::FreeConstAliasId: ::rustc_serialize::Decodable<__D>,
            I::InherentAssocConstId: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        AliasTermKind::ProjectionTy {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    1usize => {
                        AliasTermKind::InherentTy {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    2usize => {
                        AliasTermKind::OpaqueTy {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    3usize => {
                        AliasTermKind::FreeTy {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    4usize => {
                        AliasTermKind::AnonConst {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    5usize => {
                        AliasTermKind::ProjectionConst {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    6usize => {
                        AliasTermKind::FreeConst {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    7usize => {
                        AliasTermKind::InherentConst {
                            def_id: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AliasTermKind`, expected 0..8, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            AliasTermKind<I> where
            I::TraitAssocTyId: ::rustc_data_structures::stable_hash::StableHash,
            I::InherentAssocTyId: ::rustc_data_structures::stable_hash::StableHash,
            I::OpaqueTyId: ::rustc_data_structures::stable_hash::StableHash,
            I::FreeTyAliasId: ::rustc_data_structures::stable_hash::StableHash,
            I::AnonConstId: ::rustc_data_structures::stable_hash::StableHash,
            I::TraitAssocConstId: ::rustc_data_structures::stable_hash::StableHash,
            I::FreeConstAliasId: ::rustc_data_structures::stable_hash::StableHash,
            I::InherentAssocConstId: ::rustc_data_structures::stable_hash::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    AliasTermKind::ProjectionTy { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::InherentTy { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::OpaqueTy { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::FreeTy { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::AnonConst { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::ProjectionConst { def_id: ref __binding_0 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::FreeConst { def_id: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    AliasTermKind::InherentConst { def_id: ref __binding_0 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
29)]
30pub enum AliasTermKind<I: Interner> {
31    /// A projection `<Type as Trait>::AssocType`.
32    ///
33    /// Can get normalized away if monomorphic enough.
34    ///
35    /// The `def_id` is the `DefId` of the `TraitItem` for the associated type.
36    ///
37    /// Note that the `def_id` is not the `DefId` of the `TraitRef` containing this
38    /// associated type, which is in `interner.associated_item(def_id).container`,
39    /// aka. `interner.parent(def_id)`.
40    ProjectionTy { def_id: I::TraitAssocTyId },
41
42    /// An associated type in an inherent `impl`
43    ///
44    /// The `def_id` is the `DefId` of the `ImplItem` for the associated type.
45    InherentTy { def_id: I::InherentAssocTyId },
46
47    /// An opaque type (usually from `impl Trait` in type aliases or function return types)
48    ///
49    /// `def_id` is the `DefId` of the `OpaqueType` item.
50    ///
51    /// Can only be normalized away in `PostAnalysis` mode or its defining scope.
52    ///
53    /// During codegen, `interner.type_of(def_id)` can be used to get the type of the
54    /// underlying type if the type is an opaque.
55    OpaqueTy { def_id: I::OpaqueTyId },
56
57    /// A type alias that actually checks its trait bounds.
58    ///
59    /// Currently only used if the type alias references opaque types.
60    /// Can always be normalized away.
61    FreeTy { def_id: I::FreeTyAliasId },
62
63    /// An anonymous constant.
64    AnonConst { def_id: I::AnonConstId },
65    /// A const alias coming from an associated const.
66    ProjectionConst { def_id: I::TraitAssocConstId },
67    /// A top level const item not part of a trait or impl.
68    FreeConst { def_id: I::FreeConstAliasId },
69    /// An associated const in an inherent `impl`
70    InherentConst { def_id: I::InherentAssocConstId },
71}
72
73impl<I: Interner> AliasTermKind<I> {
74    pub fn descr(self) -> &'static str {
75        match self {
76            AliasTermKind::ProjectionTy { .. } => "associated type",
77            AliasTermKind::ProjectionConst { .. } => "associated const",
78            AliasTermKind::InherentTy { .. } => "inherent associated type",
79            AliasTermKind::InherentConst { .. } => "inherent associated const",
80            AliasTermKind::OpaqueTy { .. } => "opaque type",
81            AliasTermKind::FreeTy { .. } => "type alias",
82            AliasTermKind::FreeConst { .. } => "const alias",
83            AliasTermKind::AnonConst { .. } => "anonymous constant",
84        }
85    }
86
87    pub fn is_type(self) -> bool {
88        match self {
89            AliasTermKind::ProjectionTy { .. }
90            | AliasTermKind::InherentTy { .. }
91            | AliasTermKind::OpaqueTy { .. }
92            | AliasTermKind::FreeTy { .. } => true,
93
94            AliasTermKind::AnonConst { .. }
95            | AliasTermKind::ProjectionConst { .. }
96            | AliasTermKind::InherentConst { .. }
97            | AliasTermKind::FreeConst { .. } => false,
98        }
99    }
100
101    pub fn is_trait_projection(self) -> bool {
102        match self {
103            AliasTermKind::ProjectionTy { .. } | AliasTermKind::ProjectionConst { .. } => true,
104            AliasTermKind::InherentTy { .. }
105            | AliasTermKind::OpaqueTy { .. }
106            | AliasTermKind::FreeTy { .. }
107            | AliasTermKind::AnonConst { .. }
108            | AliasTermKind::FreeConst { .. }
109            | AliasTermKind::InherentConst { .. } => false,
110        }
111    }
112}
113
114impl<I: Interner> From<ty::AliasTyKind<I>> for AliasTermKind<I> {
115    fn from(value: ty::AliasTyKind<I>) -> Self {
116        match value {
117            ty::Projection { def_id } => AliasTermKind::ProjectionTy { def_id },
118            ty::Opaque { def_id } => AliasTermKind::OpaqueTy { def_id },
119            ty::Free { def_id } => AliasTermKind::FreeTy { def_id },
120            ty::Inherent { def_id } => AliasTermKind::InherentTy { def_id },
121        }
122    }
123}
124
125impl<I: Interner> From<ty::AliasConstKind<I>> for AliasTermKind<I> {
126    fn from(value: ty::AliasConstKind<I>) -> Self {
127        match value {
128            ty::AliasConstKind::Projection { def_id } => AliasTermKind::ProjectionConst { def_id },
129            ty::AliasConstKind::Inherent { def_id } => AliasTermKind::InherentConst { def_id },
130            ty::AliasConstKind::Free { def_id } => AliasTermKind::FreeConst { def_id },
131            ty::AliasConstKind::Anon { def_id } => AliasTermKind::AnonConst { def_id },
132        }
133    }
134}
135
136impl<I: Interner> AliasTerm<I> {
137    pub fn new_from_args(
138        interner: I,
139        kind: AliasTermKind<I>,
140        args: I::GenericArgs,
141    ) -> AliasTerm<I> {
142        if truecfg!(debug_assertions) {
143            let def_id = match kind {
144                AliasTermKind::ProjectionTy { def_id } => def_id.into(),
145                AliasTermKind::InherentTy { def_id } => def_id.into(),
146                AliasTermKind::OpaqueTy { def_id } => def_id.into(),
147                AliasTermKind::FreeTy { def_id } => def_id.into(),
148                AliasTermKind::AnonConst { def_id } => def_id.into(),
149                AliasTermKind::ProjectionConst { def_id } => def_id.into(),
150                AliasTermKind::FreeConst { def_id } => def_id.into(),
151                AliasTermKind::InherentConst { def_id } => def_id.into(),
152            };
153            interner.debug_assert_args_compatible(def_id, args);
154        }
155        AliasTerm { kind, args, _use_alias_new_instead: () }
156    }
157
158    pub fn new(
159        interner: I,
160        kind: AliasTermKind<I>,
161        args: impl IntoIterator<Item: Into<I::GenericArg>>,
162    ) -> AliasTerm<I> {
163        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
164        Self::new_from_args(interner, kind, args)
165    }
166
167    pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
168        let kind = interner.alias_term_kind_from_def_id(def_id);
169        Self::new_from_args(interner, kind, args)
170    }
171
172    pub fn expect_ty(self) -> ty::AliasTy<I> {
173        let kind = match self.kind {
174            AliasTermKind::ProjectionTy { def_id } => ty::AliasTyKind::Projection { def_id },
175            AliasTermKind::InherentTy { def_id } => ty::AliasTyKind::Inherent { def_id },
176            AliasTermKind::OpaqueTy { def_id } => ty::AliasTyKind::Opaque { def_id },
177            AliasTermKind::FreeTy { def_id } => ty::AliasTyKind::Free { def_id },
178            kind @ (AliasTermKind::InherentConst { .. }
179            | AliasTermKind::FreeConst { .. }
180            | AliasTermKind::AnonConst { .. }
181            | AliasTermKind::ProjectionConst { .. }) => {
182                {
    ::core::panicking::panic_fmt(format_args!("Cannot turn `{0}` into `AliasTy`",
            kind.descr()));
}panic!("Cannot turn `{}` into `AliasTy`", kind.descr())
183            }
184        };
185        ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () }
186    }
187
188    pub fn expect_ct(self) -> ty::AliasConst<I> {
189        let kind = match self.kind {
190            AliasTermKind::InherentConst { def_id } => ty::AliasConstKind::Inherent { def_id },
191            AliasTermKind::FreeConst { def_id } => ty::AliasConstKind::Free { def_id },
192            AliasTermKind::AnonConst { def_id } => ty::AliasConstKind::Anon { def_id },
193            AliasTermKind::ProjectionConst { def_id } => ty::AliasConstKind::Projection { def_id },
194            kind @ (AliasTermKind::ProjectionTy { .. }
195            | AliasTermKind::InherentTy { .. }
196            | AliasTermKind::OpaqueTy { .. }
197            | AliasTermKind::FreeTy { .. }) => {
198                {
    ::core::panicking::panic_fmt(format_args!("Cannot turn `{0}` into `AliasConst`",
            kind.descr()));
}panic!("Cannot turn `{}` into `AliasConst`", kind.descr())
199            }
200        };
201        ty::AliasConst { kind, args: self.args, _use_alias_new_instead: () }
202    }
203
204    pub fn to_term(self, interner: I, is_rigid: ty::IsRigid) -> I::Term {
205        let alias_ty = |kind| {
206            Ty::new_alias(interner, is_rigid, ty::AliasTy::new_from_args(interner, kind, self.args))
207                .into()
208        };
209        let alias_const = |kind| {
210            I::Const::new_alias(interner, is_rigid, ty::AliasConst::new(interner, kind, self.args))
211                .into()
212        };
213        match self.kind {
214            AliasTermKind::FreeConst { def_id } => alias_const(ty::AliasConstKind::Free { def_id }),
215            AliasTermKind::InherentConst { def_id } => {
216                alias_const(ty::AliasConstKind::Inherent { def_id })
217            }
218            AliasTermKind::AnonConst { def_id } => alias_const(ty::AliasConstKind::Anon { def_id }),
219            AliasTermKind::ProjectionConst { def_id } => {
220                alias_const(ty::AliasConstKind::Projection { def_id })
221            }
222            AliasTermKind::ProjectionTy { def_id } => alias_ty(ty::Projection { def_id }),
223            AliasTermKind::InherentTy { def_id } => alias_ty(ty::Inherent { def_id }),
224            AliasTermKind::OpaqueTy { def_id } => alias_ty(ty::Opaque { def_id }),
225            AliasTermKind::FreeTy { def_id } => alias_ty(ty::Free { def_id }),
226        }
227    }
228
229    pub fn with_args(self, interner: I, args: I::GenericArgs) -> Self {
230        Self::new_from_args(interner, self.kind, args)
231    }
232
233    pub fn expect_projection_ty_def_id(self) -> I::TraitAssocTyId {
234        match self.kind {
235            AliasTermKind::ProjectionTy { def_id } => def_id,
236            kind => {
    ::core::panicking::panic_fmt(format_args!("expected projection ty, found {0:?}",
            kind));
}panic!("expected projection ty, found {kind:?}"),
237        }
238    }
239
240    pub fn expect_opaque_ty_def_id(self) -> I::OpaqueTyId {
241        match self.kind {
242            AliasTermKind::OpaqueTy { def_id } => def_id,
243            kind => {
    ::core::panicking::panic_fmt(format_args!("expected opaque ty, found {0:?}",
            kind));
}panic!("expected opaque ty, found {kind:?}"),
244        }
245    }
246}
247
248/// The following methods work only with (trait) associated term projections.
249// FIXME: Replace by an impl on Alias<ProjectionAliasTermKind>
250impl<I: Interner> AliasTerm<I> {
251    pub fn self_ty(self) -> I::Ty {
252        self.args.type_at(0)
253    }
254
255    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
256        AliasTerm::new(
257            interner,
258            self.kind,
259            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
260        )
261    }
262
263    pub fn expect_projection_def_id(self) -> I::TraitAssocTermId {
264        match self.kind {
265            AliasTermKind::ProjectionTy { def_id } => def_id.into(),
266            AliasTermKind::ProjectionConst { def_id } => def_id.into(),
267            kind => {
    ::core::panicking::panic_fmt(format_args!("expected projection alias, found {0:?}",
            kind));
}panic!("expected projection alias, found {kind:?}"),
268        }
269    }
270
271    pub fn trait_def_id(self, interner: I) -> I::TraitId {
272        interner.projection_parent(self.expect_projection_def_id())
273    }
274
275    /// Extracts the underlying trait reference and own args from this projection.
276    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
277    /// then this function would return a `T: StreamingIterator` trait reference and
278    /// `['a]` as the own args.
279    pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
280        interner.trait_ref_and_own_args_for_alias(self.expect_projection_def_id(), self.args)
281    }
282
283    /// Extracts the underlying trait reference from this projection.
284    /// For example, if this is a projection of `<T as Iterator>::Item`,
285    /// then this function would return a `T: Iterator` trait reference.
286    ///
287    /// WARNING: This will drop the args for generic associated types
288    /// consider calling [Self::trait_ref_and_own_args] to get those
289    /// as well.
290    pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
291        self.trait_ref_and_own_args(interner).0
292    }
293
294    /// Extract the own args from this projection.
295    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
296    /// then this function would return the slice `['a]` as the own args.
297    pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
298        self.trait_ref_and_own_args(interner).1
299    }
300}
301
302/// The following methods work only with inherent associated term projections.
303// FIXME: Replace by an impl on Alias<InherentAliasTermKind>
304impl<I: Interner> AliasTerm<I> {
305    pub fn expect_inherent_def_id(self) -> I::InherentAssocTermId {
306        match self.kind {
307            AliasTermKind::InherentTy { def_id } => def_id.into(),
308            AliasTermKind::InherentConst { def_id } => def_id.into(),
309            kind => {
    ::core::panicking::panic_fmt(format_args!("expected inherent alias, found {0:?}",
            kind));
}panic!("expected inherent alias, found {kind:?}"),
310        }
311    }
312
313    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
314    ///
315    /// Does the following transformation:
316    ///
317    /// ```text
318    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
319    ///
320    ///     I_i impl args
321    ///     P_j GAT args
322    /// ```
323    pub fn rebase_inherent_args_onto_impl(
324        self,
325        impl_args: I::GenericArgs,
326        interner: I,
327    ) -> I::GenericArgs {
328        if true {
    if !#[allow(non_exhaustive_omitted_patterns)] match self.kind {
                AliasTermKind::InherentTy { .. } |
                    AliasTermKind::InherentConst { .. } => true,
                _ => false,
            } {
        ::core::panicking::panic("assertion failed: matches!(self.kind, AliasTermKind::InherentTy { .. } |\n    AliasTermKind::InherentConst { .. })")
    };
};debug_assert!(matches!(
329            self.kind,
330            AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConst { .. }
331        ));
332        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
333    }
334}
335
336/// The following methods work only with free term aliases.
337// FIXME: Replace by an impl on Alias<FreeAliasTermKind>
338impl<I: Interner> AliasTerm<I> {
339    pub fn expect_free_def_id(self) -> I::FreeTermAliasId {
340        match self.kind {
341            AliasTermKind::FreeTy { def_id } => def_id.into(),
342            AliasTermKind::FreeConst { def_id } => def_id.into(),
343            kind => {
    ::core::panicking::panic_fmt(format_args!("expected free alias, found {0:?}",
            kind));
}panic!("expected free alias, found {kind:?}"),
344        }
345    }
346}
347
348impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
349    fn from(ty: ty::AliasTy<I>) -> Self {
350        AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () }
351    }
352}
353
354impl<I: Interner> From<ty::AliasConst<I>> for AliasTerm<I> {
355    fn from(ty: ty::AliasConst<I>) -> Self {
356        AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () }
357    }
358}