1use rustc_ast::{LitFloatType, LitIntType, LitKind};
2use rustc_hir;
3use rustc_hir::attrs::lang_items::LangItem;
4use rustc_macros::StableHash;
5
6use crate::ty::{self, Ty, TyCtxt};
7
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<Option<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_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<LitKind>;
let _: ::core::cmp::AssertParamIsEq<Option<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> ::rustc_data_structures::stable_hash::StableHash for
LitToConstInput<'tcx> {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
LitToConstInput {
lit: ref __binding_0,
ty: ref __binding_1,
neg: ref __binding_2 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
10pub struct LitToConstInput<'tcx> {
11 pub lit: LitKind,
13 pub ty: Option<Ty<'tcx>>,
18 pub neg: bool,
20}
21
22pub fn const_lit_matches_ty<'tcx>(
24 tcx: TyCtxt<'tcx>,
25 kind: &LitKind,
26 ty: Ty<'tcx>,
27 neg: bool,
28) -> bool {
29 match (*kind, ty.kind()) {
30 (LitKind::Str(..), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => true,
31 (LitKind::Str(..), ty::Str) if tcx.features().deref_patterns() => true,
32 (LitKind::ByteStr(..), ty::Ref(_, inner_ty, _))
33 if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind()
34 && #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Uint(ty::UintTy::U8) => true,
_ => false,
}matches!(ty.kind(), ty::Uint(ty::UintTy::U8)) =>
35 {
36 true
37 }
38 (LitKind::ByteStr(..), ty::Slice(inner_ty) | ty::Array(inner_ty, _))
39 if tcx.features().deref_patterns()
40 && #[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)) =>
41 {
42 true
43 }
44 (LitKind::Byte(..), ty::Uint(ty::UintTy::U8)) => true,
45 (LitKind::CStr(..), ty::Ref(_, inner_ty, _))
46 if #[allow(non_exhaustive_omitted_patterns)] match inner_ty.kind() {
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr) => true,
_ => false,
}matches!(inner_ty.kind(), ty::Adt(def, _)
47 if tcx.is_lang_item(def.did(), LangItem::CStr)) =>
48 {
49 true
50 }
51 (LitKind::Int(_, LitIntType::Unsigned(lit_ty)), ty::Uint(expect_ty)) if !neg => {
52 lit_ty == *expect_ty
53 }
54 (LitKind::Int(_, LitIntType::Signed(lit_ty)), ty::Int(expect_ty)) => lit_ty == *expect_ty,
55 (LitKind::Int(_, LitIntType::Unsuffixed), ty::Uint(_)) if !neg => true,
56 (LitKind::Int(_, LitIntType::Unsuffixed), ty::Int(_)) => true,
57 (LitKind::Bool(..), ty::Bool) => true,
58 (LitKind::Float(_, LitFloatType::Suffixed(lit_ty)), ty::Float(expect_ty)) => {
59 lit_ty == *expect_ty
60 }
61 (LitKind::Float(_, LitFloatType::Unsuffixed), ty::Float(_)) => true,
62 (LitKind::Char(..), ty::Char) => true,
63 (LitKind::Err(..), _) => true,
64 _ => false,
65 }
66}