tokio/util/
typeid.rs
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(mem::transmute_copy::<Src, Target>(&x))
13 } else {
14 Err(x)
15 }
16}
17
18#[inline(always)]
20fn nonstatic_typeid<T>() -> TypeId
21where
22 T: ?Sized,
23{
24 trait NonStaticAny {
25 fn get_type_id(&self) -> TypeId
26 where
27 Self: 'static;
28 }
29
30 impl<T: ?Sized> NonStaticAny for PhantomData<T> {
31 #[inline(always)]
32 fn get_type_id(&self) -> TypeId
33 where
34 Self: 'static,
35 {
36 TypeId::of::<T>()
37 }
38 }
39
40 let phantom_data = PhantomData::<T>;
41 NonStaticAny::get_type_id(unsafe {
42 mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom_data)
43 })
44}