konst_macro_rules/
type_eq.rs1use core::marker::PhantomData;
2
3mod __ {
4 use super::*;
5
6 pub struct TypeEq<L: ?Sized, R: ?Sized>(
12 PhantomData<(
13 fn(PhantomData<L>) -> PhantomData<L>,
14 fn(PhantomData<R>) -> PhantomData<R>,
15 )>,
16 );
17
18 impl<L: ?Sized> TypeEq<L, L> {
19 pub const NEW: Self = TypeEq(PhantomData);
21 }
22}
23pub use __::TypeEq;
24
25impl<L: ?Sized, R: ?Sized> Copy for TypeEq<L, R> {}
26
27impl<L: ?Sized, R: ?Sized> Clone for TypeEq<L, R> {
28 fn clone(&self) -> Self {
29 *self
30 }
31}
32
33impl<L, R> TypeEq<L, R> {
34 const ARE_SAME_TYPE: Amb = {
36 let approx_same_type = {
39 core::mem::size_of::<L>() == core::mem::size_of::<R>()
40 && core::mem::align_of::<L>() == core::mem::align_of::<R>()
41 && core::mem::size_of::<Option<L>>() == core::mem::size_of::<Option<R>>()
42 && core::mem::align_of::<Option<L>>() == core::mem::align_of::<Option<R>>()
43 };
44
45 if approx_same_type {
46 Amb::Indefinite
47 } else {
48 Amb::No
49 }
50 };
51
52 #[inline(always)]
54 pub const fn reachability_hint(self) {
55 if let Amb::No = Self::ARE_SAME_TYPE {
56 #[cfg(feature = "rust_1_57")]
59 unsafe {
60 core::hint::unreachable_unchecked()
61 }
62 #[cfg(not(feature = "rust_1_57"))]
63 #[allow(unreachable_code)]
64 unsafe {
65 match crate::__priv_transmute!((), core::convert::Infallible, ()) {}
66 }
67 }
68 }
69
70 #[inline(always)]
73 pub const fn to_right(self, from: L) -> R {
74 self.reachability_hint();
75
76 unsafe { crate::__priv_transmute!(L, R, from) }
77 }
78}
79
80enum Amb {
81 Indefinite,
83 No,
85}