1use rustc_span::bug;
4
5use crate::mir;
6use crate::ty::{self, Ty};
7
8#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for CastTy<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for CastTy<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for CastTy<'tcx> {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<ty::TypeAndMut<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CastTy<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Int => ::core::fmt::Formatter::write_str(f, "Int"),
Self::CEnum => ::core::fmt::Formatter::write_str(f, "CEnum"),
Self::Bool => ::core::fmt::Formatter::write_str(f, "Bool"),
Self::Char => ::core::fmt::Formatter::write_str(f, "Char"),
Self::Float => ::core::fmt::Formatter::write_str(f, "Float"),
Self::FnPtr => ::core::fmt::Formatter::write_str(f, "FnPtr"),
Self::Ptr(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ptr",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for CastTy<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for CastTy<'tcx> {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Ptr(__self_0), Self::Ptr(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for CastTy<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ty::TypeAndMut<'tcx>>;
}
}Eq)]
10pub enum CastTy<'tcx> {
11 Int,
13 CEnum,
15 Bool,
16 Char,
17 Float,
19 FnPtr,
21 Ptr(ty::TypeAndMut<'tcx>),
23}
24
25impl<'tcx> CastTy<'tcx> {
26 pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
29 match *t.kind() {
30 ty::Bool => Some(CastTy::Bool),
31 ty::Char => Some(CastTy::Char),
32 ty::Int(_) | ty::Uint(_) | ty::Infer(ty::InferTy::IntVar(_)) => Some(CastTy::Int),
33 ty::Float(_) | ty::Infer(ty::InferTy::FloatVar(_)) => Some(CastTy::Float),
34 ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::CEnum),
35 ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })),
36 ty::FnPtr(..) => Some(CastTy::FnPtr),
37 _ => None,
38 }
39 }
40
41 pub fn is_int_like(self) -> bool {
42 match self {
43 CastTy::Int | CastTy::CEnum | CastTy::Bool | CastTy::Char => true,
44 CastTy::Float | CastTy::FnPtr | CastTy::Ptr(_) => false,
45 }
46 }
47}
48
49pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKind {
51 let from = CastTy::from_ty(from_ty);
52 let cast = CastTy::from_ty(cast_ty);
53 let cast_kind = match (from, cast) {
54 (Some(from), Some(cast)) if from.is_int_like() && cast.is_int_like() => {
55 mir::CastKind::IntToInt
56 }
57 (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int)) => {
58 mir::CastKind::PointerExposeProvenance
59 }
60 (Some(CastTy::Int), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
61 (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr,
62
63 (Some(CastTy::Float), Some(CastTy::Int)) => mir::CastKind::FloatToInt,
64 (Some(CastTy::Int), Some(CastTy::Float)) => mir::CastKind::IntToFloat,
65 (Some(CastTy::Float), Some(CastTy::Float)) => mir::CastKind::FloatToFloat,
66 (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PtrToPtr,
67
68 (_, _) => {
69 ::rustc_span::macros::bug_impl(None,
format_args!("Attempting to cast non-castable types {0:?} and {1:?}",
from_ty, cast_ty), Location::caller())bug!("Attempting to cast non-castable types {:?} and {:?}", from_ty, cast_ty)
70 }
71 };
72 cast_kind
73}