use core::{
any::{type_name, TypeId},
mem, ptr,
};
#[inline(always)]
pub(crate) fn type_eq<T: 'static, U: 'static>() -> bool {
mem::size_of::<T>() == mem::size_of::<U>()
&& mem::align_of::<T>() == mem::align_of::<U>()
&& mem::needs_drop::<T>() == mem::needs_drop::<U>()
&& TypeId::of::<T>() == TypeId::of::<U>()
&& type_name::<T>() == type_name::<U>()
}
#[inline(always)]
pub(crate) fn type_eq_non_static<T: ?Sized, U: ?Sized>() -> bool {
#[inline]
fn type_id_of<T: ?Sized>() -> usize {
type_id_of::<T> as usize
}
type_id_of::<T>() == type_id_of::<U>()
&& type_name::<T>() == type_name::<U>()
}
#[inline(always)]
pub(crate) unsafe fn transmute_unchecked<T, U>(value: T) -> U {
let dest = ptr::read(&value as *const T as *const U);
mem::forget(value);
dest
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn non_static_type_comparisons() {
assert!(type_eq_non_static::<u8, u8>());
assert!(type_eq_non_static::<&'static u8, &'static u8>());
assert!(type_eq_non_static::<&u8, &'static u8>());
assert!(!type_eq_non_static::<u8, i8>());
assert!(!type_eq_non_static::<u8, &'static u8>());
}
}