Skip to main content

rustc_middle/ty/
abstract_const.rs

1//! A subset of a mir body used for const evaluability checking.
2
3use rustc_errors::ErrorGuaranteed;
4use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
5
6use crate::ty::{
7    self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
8    TypeVisitableExt,
9};
10
11#[derive(#[automatically_derived]
impl ::core::hash::Hash for CastKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CastKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self { CastKind::As => "As", CastKind::Use => "Use", })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CastKind {
    #[inline]
    fn clone(&self) -> CastKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CastKind { }Copy, #[automatically_derived]
impl ::core::cmp::Ord for CastKind {
    #[inline]
    fn cmp(&self, other: &CastKind) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for CastKind {
    #[inline]
    fn partial_cmp(&self, other: &CastKind)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::PartialEq for CastKind {
    #[inline]
    fn eq(&self, other: &CastKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CastKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {}
}Eq)]
12#[derive(const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for CastKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { CastKind::As }
                    1usize => { CastKind::Use }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `CastKind`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for CastKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        CastKind::As => { 0usize }
                        CastKind::Use => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self { CastKind::As => {} CastKind::Use => {} }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for CastKind {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self { CastKind::As => {} CastKind::Use => {} }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
            for CastKind {
            fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self { CastKind::As => {} CastKind::Use => {} }
                <__V::Result as ::rustc_middle::ty::VisitorResult>::output()
            }
        }
    };TypeVisitable, const _: () =
    {
        impl<'tcx>
            ::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
            for CastKind {
            fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        CastKind::As => { CastKind::As }
                        CastKind::Use => { CastKind::Use }
                    })
            }
            fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    CastKind::As => { CastKind::As }
                    CastKind::Use => { CastKind::Use }
                }
            }
        }
    };TypeFoldable)]
13pub enum CastKind {
14    /// thir::ExprKind::As
15    As,
16    /// thir::ExprKind::Use
17    Use,
18}
19
20#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NotConstEvaluatable {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            NotConstEvaluatable::Error(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Error",
                    &__self_0),
            NotConstEvaluatable::MentionsInfer =>
                ::core::fmt::Formatter::write_str(f, "MentionsInfer"),
            NotConstEvaluatable::MentionsParam =>
                ::core::fmt::Formatter::write_str(f, "MentionsParam"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for NotConstEvaluatable { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NotConstEvaluatable {
    #[inline]
    fn clone(&self) -> NotConstEvaluatable {
        let _: ::core::clone::AssertParamIsClone<ErrorGuaranteed>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for NotConstEvaluatable {
    #[inline]
    fn eq(&self, other: &NotConstEvaluatable) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (NotConstEvaluatable::Error(__self_0),
                    NotConstEvaluatable::Error(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NotConstEvaluatable {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<ErrorGuaranteed>;
    }
}Eq, const _: () =
    {
        impl<'__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for NotConstEvaluatable {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    NotConstEvaluatable::Error(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    NotConstEvaluatable::MentionsInfer => {}
                    NotConstEvaluatable::MentionsParam => {}
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for NotConstEvaluatable {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        NotConstEvaluatable::Error(ref __binding_0) => { 0usize }
                        NotConstEvaluatable::MentionsInfer => { 1usize }
                        NotConstEvaluatable::MentionsParam => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    NotConstEvaluatable::Error(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    NotConstEvaluatable::MentionsInfer => {}
                    NotConstEvaluatable::MentionsParam => {}
                }
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for NotConstEvaluatable {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        NotConstEvaluatable::Error(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { NotConstEvaluatable::MentionsInfer }
                    2usize => { NotConstEvaluatable::MentionsParam }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `NotConstEvaluatable`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable)]
21pub enum NotConstEvaluatable {
22    Error(ErrorGuaranteed),
23    MentionsInfer,
24    MentionsParam,
25}
26
27impl From<ErrorGuaranteed> for NotConstEvaluatable {
28    fn from(e: ErrorGuaranteed) -> NotConstEvaluatable {
29        NotConstEvaluatable::Error(e)
30    }
31}
32
33pub type BoundAbstractConst<'tcx> =
34    Result<Option<EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed>;
35
36impl<'tcx> TyCtxt<'tcx> {
37    pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
38        struct Expander<'tcx> {
39            tcx: TyCtxt<'tcx>,
40        }
41
42        impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Expander<'tcx> {
43            fn cx(&self) -> TyCtxt<'tcx> {
44                self.tcx
45            }
46            fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
47                if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) {
48                    ty.super_fold_with(self)
49                } else {
50                    ty
51                }
52            }
53            fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
54                let ct = match c.kind() {
55                    ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
56                        Err(e) => ty::Const::new_error(self.tcx, e),
57                        Ok(Some(bac)) => {
58                            let args = self.tcx.erase_and_anonymize_regions(uv.args);
59                            let bac = bac.instantiate(self.tcx, args);
60                            return bac.fold_with(self);
61                        }
62                        Ok(None) => c,
63                    },
64                    _ => c,
65                };
66                ct.super_fold_with(self)
67            }
68        }
69        ac.fold_with(&mut Expander { tcx: self })
70    }
71}