1use rustc_ast::{LitFloatType, LitIntType, LitKind};
2use rustc_hir;
3use rustc_macros::HashStable;
4
5use crate::ty::{self, Ty, TyCtxt};
6
7#[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, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for LitToConstInput<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::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 pub lit: LitKind,
12 pub ty: Option<Ty<'tcx>>,
17 pub neg: bool,
19}
20
21pub fn const_lit_matches_ty<'tcx>(
23 tcx: TyCtxt<'tcx>,
24 kind: &LitKind,
25 ty: Ty<'tcx>,
26 neg: bool,
27) -> bool {
28 match (*kind, ty.kind()) {
29 (LitKind::Str(..), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => true,
30 (LitKind::Str(..), ty::Str) if tcx.features().deref_patterns() => true,
31 (LitKind::ByteStr(..), ty::Ref(_, inner_ty, _))
32 if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind()
33 && #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Uint(ty::UintTy::U8) => true,
_ => false,
}matches!(ty.kind(), ty::Uint(ty::UintTy::U8)) =>
34 {
35 true
36 }
37 (LitKind::ByteStr(..), ty::Slice(inner_ty) | ty::Array(inner_ty, _))
38 if tcx.features().deref_patterns()
39 && #[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)) =>
40 {
41 true
42 }
43 (LitKind::Byte(..), ty::Uint(ty::UintTy::U8)) => true,
44 (LitKind::CStr(..), ty::Ref(_, inner_ty, _))
45 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, _)
46 if tcx.is_lang_item(def.did(), rustc_hir::LangItem::CStr)) =>
47 {
48 true
49 }
50 (LitKind::Int(_, LitIntType::Unsigned(lit_ty)), ty::Uint(expect_ty)) if !neg => {
51 lit_ty == *expect_ty
52 }
53 (LitKind::Int(_, LitIntType::Signed(lit_ty)), ty::Int(expect_ty)) => lit_ty == *expect_ty,
54 (LitKind::Int(_, LitIntType::Unsuffixed), ty::Uint(_)) if !neg => true,
55 (LitKind::Int(_, LitIntType::Unsuffixed), ty::Int(_)) => true,
56 (LitKind::Bool(..), ty::Bool) => true,
57 (LitKind::Float(_, LitFloatType::Suffixed(lit_ty)), ty::Float(expect_ty)) => {
58 lit_ty == *expect_ty
59 }
60 (LitKind::Float(_, LitFloatType::Unsuffixed), ty::Float(_)) => true,
61 (LitKind::Char(..), ty::Char) => true,
62 (LitKind::Err(..), _) => true,
63 _ => false,
64 }
65}