@@ -6,7 +6,7 @@ extern crate alloc;
66extern crate std;
77
88use alloc:: { borrow:: Cow , collections:: BTreeMap , vec:: Vec } ;
9- use core:: hash:: BuildHasherDefault ;
9+ use core:: { any :: TypeId , hash:: BuildHasherDefault , marker :: PhantomData } ;
1010use indexmap:: IndexMap ;
1111use serde:: { Deserialize , Serialize } ;
1212use serde_with:: skip_serializing_none;
@@ -142,27 +142,32 @@ pub enum Schema {
142142}
143143
144144#[ derive( Hash , PartialEq , Eq ) ]
145- pub struct Identifier ( usize ) ;
145+ pub struct Identifier ( TypeId ) ;
146146
147147impl Identifier {
148148 pub fn of < T > ( ) -> Self
149149 where
150150 T : ?Sized ,
151151 {
152- // Don't do this at home. I'm a professional.
152+ // Taken from <sagebind/castaway>: https://github.com/sagebind/castaway/blob/a7baeab32d75d0f105d1415210a2867d213f8818/src/utils.rs#L36
153153 //
154- // This is a hack based on the assumption that each type has will produce a unique monomorphized function.
155- // Therefore each function has a distinct function pointer.
156- //
157- // The compiler _might_ break this assumption in the future.
158- #[ inline]
159- fn type_id_of < T : ?Sized > ( ) -> usize {
160- type_id_of :: < T > as usize
154+ // Seems more robust than the previous implementation.
155+ trait NonStaticAny {
156+ fn get_type_id ( & self ) -> TypeId where Self : ' static ;
157+ }
158+
159+ impl < T : ?Sized > NonStaticAny for PhantomData < T > {
160+ fn get_type_id ( & self ) -> TypeId where Self : ' static {
161+ TypeId :: of :: < T > ( )
162+ }
161163 }
162164
163- debug_assert_eq ! ( type_id_of:: <T >( ) , type_id_of:: <T >( ) ) ;
165+ let phantom = PhantomData :: < T > ;
166+ let ty_id = NonStaticAny :: get_type_id ( unsafe {
167+ core:: mem:: transmute :: < & dyn NonStaticAny , & ( dyn NonStaticAny + ' static ) > ( & phantom)
168+ } ) ;
164169
165- Self ( type_id_of :: < T > ( ) )
170+ Identifier ( ty_id )
166171 }
167172}
168173
0 commit comments