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::UnevaluatedConstId: ::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::UnevaluatedConstId: ::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::UnevaluatedConstId: ::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::UnevaluatedConstId: ::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::UnevaluatedConstId: ::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 unevaluated anonymous constants.
64    AnonConst { def_id: I::UnevaluatedConstId },
65    /// An unevaluated const 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 { .. } => "unevaluated constant",
83            AliasTermKind::AnonConst { .. } => "unevaluated 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::UnevaluatedConstKind<I>> for AliasTermKind<I> {
126    fn from(value: ty::UnevaluatedConstKind<I>) -> Self {
127        match value {
128            ty::UnevaluatedConstKind::Projection { def_id } => {
129                AliasTermKind::ProjectionConst { def_id }
130            }
131            ty::UnevaluatedConstKind::Inherent { def_id } => {
132                AliasTermKind::InherentConst { def_id }
133            }
134            ty::UnevaluatedConstKind::Free { def_id } => AliasTermKind::FreeConst { def_id },
135            ty::UnevaluatedConstKind::Anon { def_id } => AliasTermKind::AnonConst { def_id },
136        }
137    }
138}
139
140impl<I: Interner> AliasTerm<I> {
141    pub fn new_from_args(
142        interner: I,
143        kind: AliasTermKind<I>,
144        args: I::GenericArgs,
145    ) -> AliasTerm<I> {
146        if truecfg!(debug_assertions) {
147            let def_id = match kind {
148                AliasTermKind::ProjectionTy { def_id } => def_id.into(),
149                AliasTermKind::InherentTy { def_id } => def_id.into(),
150                AliasTermKind::OpaqueTy { def_id } => def_id.into(),
151                AliasTermKind::FreeTy { def_id } => def_id.into(),
152                AliasTermKind::AnonConst { def_id } => def_id.into(),
153                AliasTermKind::ProjectionConst { def_id } => def_id.into(),
154                AliasTermKind::FreeConst { def_id } => def_id.into(),
155                AliasTermKind::InherentConst { def_id } => def_id.into(),
156            };
157            interner.debug_assert_args_compatible(def_id, args);
158        }
159        AliasTerm { kind, args, _use_alias_new_instead: () }
160    }
161
162    pub fn new(
163        interner: I,
164        kind: AliasTermKind<I>,
165        args: impl IntoIterator<Item: Into<I::GenericArg>>,
166    ) -> AliasTerm<I> {
167        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
168        Self::new_from_args(interner, kind, args)
169    }
170
171    pub fn new_from_def_id(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
172        let kind = interner.alias_term_kind_from_def_id(def_id);
173        Self::new_from_args(interner, kind, args)
174    }
175
176    pub fn expect_ty(self) -> ty::AliasTy<I> {
177        let kind = match self.kind {
178            AliasTermKind::ProjectionTy { def_id } => ty::AliasTyKind::Projection { def_id },
179            AliasTermKind::InherentTy { def_id } => ty::AliasTyKind::Inherent { def_id },
180            AliasTermKind::OpaqueTy { def_id } => ty::AliasTyKind::Opaque { def_id },
181            AliasTermKind::FreeTy { def_id } => ty::AliasTyKind::Free { def_id },
182            kind @ (AliasTermKind::InherentConst { .. }
183            | AliasTermKind::FreeConst { .. }
184            | AliasTermKind::AnonConst { .. }
185            | AliasTermKind::ProjectionConst { .. }) => {
186                {
    ::core::panicking::panic_fmt(format_args!("Cannot turn `{0}` into `AliasTy`",
            kind.descr()));
}panic!("Cannot turn `{}` into `AliasTy`", kind.descr())
187            }
188        };
189        ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () }
190    }
191
192    pub fn expect_ct(self) -> ty::UnevaluatedConst<I> {
193        let kind = match self.kind {
194            AliasTermKind::InherentConst { def_id } => {
195                ty::UnevaluatedConstKind::Inherent { def_id }
196            }
197            AliasTermKind::FreeConst { def_id } => ty::UnevaluatedConstKind::Free { def_id },
198            AliasTermKind::AnonConst { def_id } => ty::UnevaluatedConstKind::Anon { def_id },
199            AliasTermKind::ProjectionConst { def_id } => {
200                ty::UnevaluatedConstKind::Projection { def_id }
201            }
202            kind @ (AliasTermKind::ProjectionTy { .. }
203            | AliasTermKind::InherentTy { .. }
204            | AliasTermKind::OpaqueTy { .. }
205            | AliasTermKind::FreeTy { .. }) => {
206                {
    ::core::panicking::panic_fmt(format_args!("Cannot turn `{0}` into `UnevaluatedConst`",
            kind.descr()));
}panic!("Cannot turn `{}` into `UnevaluatedConst`", kind.descr())
207            }
208        };
209        ty::UnevaluatedConst { kind, args: self.args, _use_alias_new_instead: () }
210    }
211
212    pub fn to_term(self, interner: I, is_rigid: ty::IsRigid) -> I::Term {
213        let alias_ty = |kind| {
214            Ty::new_alias(interner, is_rigid, ty::AliasTy::new_from_args(interner, kind, self.args))
215                .into()
216        };
217        let unevaluated_const = |kind| {
218            I::Const::new_unevaluated(
219                interner,
220                is_rigid,
221                ty::UnevaluatedConst::new(interner, kind, self.args),
222            )
223            .into()
224        };
225        match self.kind {
226            AliasTermKind::FreeConst { def_id } => {
227                unevaluated_const(ty::UnevaluatedConstKind::Free { def_id })
228            }
229            AliasTermKind::InherentConst { def_id } => {
230                unevaluated_const(ty::UnevaluatedConstKind::Inherent { def_id })
231            }
232            AliasTermKind::AnonConst { def_id } => {
233                unevaluated_const(ty::UnevaluatedConstKind::Anon { def_id })
234            }
235            AliasTermKind::ProjectionConst { def_id } => {
236                unevaluated_const(ty::UnevaluatedConstKind::Projection { def_id })
237            }
238            AliasTermKind::ProjectionTy { def_id } => alias_ty(ty::Projection { def_id }),
239            AliasTermKind::InherentTy { def_id } => alias_ty(ty::Inherent { def_id }),
240            AliasTermKind::OpaqueTy { def_id } => alias_ty(ty::Opaque { def_id }),
241            AliasTermKind::FreeTy { def_id } => alias_ty(ty::Free { def_id }),
242        }
243    }
244
245    pub fn with_args(self, interner: I, args: I::GenericArgs) -> Self {
246        Self::new_from_args(interner, self.kind, args)
247    }
248
249    pub fn expect_projection_ty_def_id(self) -> I::TraitAssocTyId {
250        match self.kind {
251            AliasTermKind::ProjectionTy { def_id } => def_id,
252            kind => {
    ::core::panicking::panic_fmt(format_args!("expected projection ty, found {0:?}",
            kind));
}panic!("expected projection ty, found {kind:?}"),
253        }
254    }
255
256    pub fn expect_opaque_ty_def_id(self) -> I::OpaqueTyId {
257        match self.kind {
258            AliasTermKind::OpaqueTy { def_id } => def_id,
259            kind => {
    ::core::panicking::panic_fmt(format_args!("expected opaque ty, found {0:?}",
            kind));
}panic!("expected opaque ty, found {kind:?}"),
260        }
261    }
262}
263
264/// The following methods work only with (trait) associated term projections.
265// FIXME: Replace by an impl on Alias<ProjectionAliasTermKind>
266impl<I: Interner> AliasTerm<I> {
267    pub fn self_ty(self) -> I::Ty {
268        self.args.type_at(0)
269    }
270
271    pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
272        AliasTerm::new(
273            interner,
274            self.kind,
275            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
276        )
277    }
278
279    pub fn expect_projection_def_id(self) -> I::TraitAssocTermId {
280        match self.kind {
281            AliasTermKind::ProjectionTy { def_id } => def_id.into(),
282            AliasTermKind::ProjectionConst { def_id } => def_id.into(),
283            kind => {
    ::core::panicking::panic_fmt(format_args!("expected projection alias, found {0:?}",
            kind));
}panic!("expected projection alias, found {kind:?}"),
284        }
285    }
286
287    pub fn trait_def_id(self, interner: I) -> I::TraitId {
288        interner.projection_parent(self.expect_projection_def_id())
289    }
290
291    /// Extracts the underlying trait reference and own args from this projection.
292    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
293    /// then this function would return a `T: StreamingIterator` trait reference and
294    /// `['a]` as the own args.
295    pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
296        interner.trait_ref_and_own_args_for_alias(self.expect_projection_def_id(), self.args)
297    }
298
299    /// Extracts the underlying trait reference from this projection.
300    /// For example, if this is a projection of `<T as Iterator>::Item`,
301    /// then this function would return a `T: Iterator` trait reference.
302    ///
303    /// WARNING: This will drop the args for generic associated types
304    /// consider calling [Self::trait_ref_and_own_args] to get those
305    /// as well.
306    pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
307        self.trait_ref_and_own_args(interner).0
308    }
309
310    /// Extract the own args from this projection.
311    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
312    /// then this function would return the slice `['a]` as the own args.
313    pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
314        self.trait_ref_and_own_args(interner).1
315    }
316}
317
318/// The following methods work only with inherent associated term projections.
319// FIXME: Replace by an impl on Alias<InherentAliasTermKind>
320impl<I: Interner> AliasTerm<I> {
321    pub fn expect_inherent_def_id(self) -> I::InherentAssocTermId {
322        match self.kind {
323            AliasTermKind::InherentTy { def_id } => def_id.into(),
324            AliasTermKind::InherentConst { def_id } => def_id.into(),
325            kind => {
    ::core::panicking::panic_fmt(format_args!("expected inherent alias, found {0:?}",
            kind));
}panic!("expected inherent alias, found {kind:?}"),
326        }
327    }
328
329    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
330    ///
331    /// Does the following transformation:
332    ///
333    /// ```text
334    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
335    ///
336    ///     I_i impl args
337    ///     P_j GAT args
338    /// ```
339    pub fn rebase_inherent_args_onto_impl(
340        self,
341        impl_args: I::GenericArgs,
342        interner: I,
343    ) -> I::GenericArgs {
344        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!(
345            self.kind,
346            AliasTermKind::InherentTy { .. } | AliasTermKind::InherentConst { .. }
347        ));
348        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
349    }
350}
351
352/// The following methods work only with free term aliases.
353// FIXME: Replace by an impl on Alias<FreeAliasTermKind>
354impl<I: Interner> AliasTerm<I> {
355    pub fn expect_free_def_id(self) -> I::FreeTermAliasId {
356        match self.kind {
357            AliasTermKind::FreeTy { def_id } => def_id.into(),
358            AliasTermKind::FreeConst { def_id } => def_id.into(),
359            kind => {
    ::core::panicking::panic_fmt(format_args!("expected free alias, found {0:?}",
            kind));
}panic!("expected free alias, found {kind:?}"),
360        }
361    }
362}
363
364impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> {
365    fn from(ty: ty::AliasTy<I>) -> Self {
366        AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () }
367    }
368}
369
370impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
371    fn from(ty: ty::UnevaluatedConst<I>) -> Self {
372        AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () }
373    }
374}