Skip to main content

rustc_middle/ty/consts/
lit.rs

1use rustc_ast::LitKind;
2use rustc_hir;
3use rustc_macros::HashStable;
4
5use crate::ty::{self, Ty, TyCtxt};
6
7/// Input argument for `tcx.lit_to_const`.
8#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for LitToConstInput<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for LitToConstInput<'tcx> {
    #[inline]
    fn clone(&self) -> LitToConstInput<'tcx> {
        let _: ::core::clone::AssertParamIsClone<LitKind>;
        let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for LitToConstInput<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LitToConstInput", "lit", &self.lit, "ty", &self.ty, "neg",
            &&self.neg)
    }
}Debug, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for LitToConstInput<'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<LitKind>;
        let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for LitToConstInput<'tcx> {
    #[inline]
    fn eq(&self, other: &LitToConstInput<'tcx>) -> bool {
        self.neg == other.neg && self.lit == other.lit && self.ty == other.ty
    }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for LitToConstInput<'tcx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.lit, state);
        ::core::hash::Hash::hash(&self.ty, state);
        ::core::hash::Hash::hash(&self.neg, state)
    }
}Hash, const _: () =
    {
        impl<'tcx, '__ctx>
            ::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
            for LitToConstInput<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LitToConstInput {
                        lit: ref __binding_0,
                        ty: ref __binding_1,
                        neg: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable)]
9pub struct LitToConstInput<'tcx> {
10    /// The absolute value of the resultant constant.
11    pub lit: LitKind,
12    /// The type of the constant.
13    pub ty: Ty<'tcx>,
14    /// If the constant is negative.
15    pub neg: bool,
16}
17
18/// Checks whether a literal can be interpreted as a const of the given type.
19pub fn const_lit_matches_ty<'tcx>(
20    tcx: TyCtxt<'tcx>,
21    kind: &LitKind,
22    ty: Ty<'tcx>,
23    neg: bool,
24) -> bool {
25    match (*kind, ty.kind()) {
26        (LitKind::Str(..), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => true,
27        (LitKind::Str(..), ty::Str) if tcx.features().deref_patterns() => true,
28        (LitKind::ByteStr(..), ty::Ref(_, inner_ty, _))
29            if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind()
30                && #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Uint(ty::UintTy::U8) => true,
    _ => false,
}matches!(ty.kind(), ty::Uint(ty::UintTy::U8)) =>
31        {
32            true
33        }
34        (LitKind::ByteStr(..), ty::Slice(inner_ty) | ty::Array(inner_ty, _))
35            if tcx.features().deref_patterns()
36                && #[allow(non_exhaustive_omitted_patterns)] match inner_ty.kind() {
    ty::Uint(ty::UintTy::U8) => true,
    _ => false,
}matches!(inner_ty.kind(), ty::Uint(ty::UintTy::U8)) =>
37        {
38            true
39        }
40        (LitKind::Byte(..), ty::Uint(ty::UintTy::U8)) => true,
41        (LitKind::CStr(..), ty::Ref(_, inner_ty, _))
42            if #[allow(non_exhaustive_omitted_patterns)] match inner_ty.kind() {
    ty::Adt(def, _) if tcx.is_lang_item(def.did(), rustc_hir::LangItem::CStr)
        => true,
    _ => false,
}matches!(inner_ty.kind(), ty::Adt(def, _)
43                if tcx.is_lang_item(def.did(), rustc_hir::LangItem::CStr)) =>
44        {
45            true
46        }
47        (LitKind::Int(..), ty::Uint(_)) if !neg => true,
48        (LitKind::Int(..), ty::Int(_)) => true,
49        (LitKind::Bool(..), ty::Bool) => true,
50        (LitKind::Float(..), ty::Float(_)) => true,
51        (LitKind::Char(..), ty::Char) => true,
52        (LitKind::Err(..), _) => true,
53        _ => false,
54    }
55}