@@ -6,7 +6,7 @@ extern crate alloc;
6
6
extern crate std;
7
7
8
8
use alloc:: { borrow:: Cow , collections:: BTreeMap , vec:: Vec } ;
9
- use core:: hash:: BuildHasherDefault ;
9
+ use core:: { any :: TypeId , hash:: BuildHasherDefault , marker :: PhantomData } ;
10
10
use indexmap:: IndexMap ;
11
11
use serde:: { Deserialize , Serialize } ;
12
12
use serde_with:: skip_serializing_none;
@@ -142,27 +142,32 @@ pub enum Schema {
142
142
}
143
143
144
144
#[ derive( Hash , PartialEq , Eq ) ]
145
- pub struct Identifier ( usize ) ;
145
+ pub struct Identifier ( TypeId ) ;
146
146
147
147
impl Identifier {
148
148
pub fn of < T > ( ) -> Self
149
149
where
150
150
T : ?Sized ,
151
151
{
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
153
153
//
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
+ }
161
163
}
162
164
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
+ } ) ;
164
169
165
- Self ( type_id_of :: < T > ( ) )
170
+ Identifier ( ty_id )
166
171
}
167
172
}
168
173
0 commit comments