1use std::{
2 any::TypeId,
3 marker::PhantomData,
4 mem::{self, ManuallyDrop},
5};
6
7pub(super) unsafe fn try_transmute<Src, Target: 'static>(x: Src) -> Result<Target, Src> {
10 if nonstatic_typeid::<Src>() == TypeId::of::<Target>() {
11 let x = ManuallyDrop::new(x);
12 Ok(unsafe { mem::transmute_copy::<Src, Target>(&x) })
14 } else {
15 Err(x)
16 }
17}
18
19#[inline(always)]
21fn nonstatic_typeid<T>() -> TypeId
22where
23 T: ?Sized,
24{
25 trait NonStaticAny {
26 fn get_type_id(&self) -> TypeId
27 where
28 Self: 'static;
29 }
30
31 impl<T: ?Sized> NonStaticAny for PhantomData<T> {
32 #[inline(always)]
33 fn get_type_id(&self) -> TypeId
34 where
35 Self: 'static,
36 {
37 TypeId::of::<T>()
38 }
39 }
40
41 let phantom_data = PhantomData::<T>;
42 NonStaticAny::get_type_id(unsafe {
43 mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom_data)
44 })
45}