File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -292,7 +292,9 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
292292
293293 s. fields . iter ( ) . for_each ( |field| {
294294 let ty = & field. ty . to_token_stream ( ) . to_string ( ) ;
295- if generics_names_raw. contains ( ty) || ty. starts_with ( "PhantomDeserData" ) {
295+ if ty. starts_with ( "PhantomDeserData" ) {
296+ methods. push ( syn:: parse_quote!( _deserialize_eps_inner_special) ) ;
297+ } else if generics_names_raw. contains ( ty) {
296298 methods. push ( syn:: parse_quote!( _deserialize_eps_inner) ) ;
297299 } else {
298300 methods. push ( syn:: parse_quote!( _deserialize_full_inner) ) ;
@@ -608,7 +610,11 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
608610 bounds : bounds_des,
609611 } ) ) ;
610612
611- if generics_names_raw. contains ( & ty. to_token_stream ( ) . to_string ( ) ) {
613+ // TODO don't do just string comparison
614+ let ty = ty. to_token_stream ( ) . to_string ( ) ;
615+ if ty. starts_with ( "PhantomDeserData" ) {
616+ methods. push ( syn:: parse_quote!( _deserialize_eps_inner_special) ) ;
617+ } else if generics_names_raw. contains ( & ty) {
612618 methods. push ( syn:: parse_quote!( _deserialize_eps_inner) ) ;
613619 } else {
614620 methods. push ( syn:: parse_quote!( _deserialize_full_inner) ) ;
Original file line number Diff line number Diff line change 1111#[ cfg( all( feature = "alloc" , not( feature = "std" ) ) ) ]
1212extern crate alloc;
1313
14- use core:: { hash:: Hash , marker:: PhantomData } ;
14+ use core:: { hash:: Hash , marker:: PhantomData , mem :: transmute } ;
1515
1616#[ cfg( feature = "derive" ) ]
1717pub use epserde_derive:: { Epserde , TypeInfo } ;
@@ -72,6 +72,21 @@ impl<T: ?Sized> PhantomDeserData<T> {
7272 }
7373}
7474
75+ impl < T : ?Sized + DeserializeInner > PhantomDeserData < T > {
76+ #[ inline( always) ]
77+ pub unsafe fn _deserialize_eps_inner_special < ' a > (
78+ _backend : & mut SliceWithPos < ' a > ,
79+ ) -> deser:: Result < PhantomDeserData < T :: DeserType < ' a > > > {
80+ // SAFETY: types are zero-length
81+ Ok ( unsafe {
82+ transmute :: <
83+ <PhantomDeserData < T > as DeserializeInner >:: DeserType < ' a > ,
84+ PhantomDeserData < T :: DeserType < ' a > > ,
85+ > ( PhantomDeserData ( PhantomData ) )
86+ } )
87+ }
88+ }
89+
7590impl < T : ?Sized > CopyType for PhantomDeserData < T > {
7691 type Copy = Zero ;
7792}
Original file line number Diff line number Diff line change @@ -160,7 +160,7 @@ fn test_only_phantom() {
160160struct DataWithPhantomDeserData < T > {
161161 data : T ,
162162 // This will deserialize to PhantomData<T::DeserType<'a>>
163- phantom : PhantomDeserData < PhantomData < T > > ,
163+ phantom : PhantomDeserData < T > ,
164164}
165165
166166/// Test that PhantomDeserData works correctly with generic types that are transformed during deserialization.
@@ -193,5 +193,5 @@ fn test_deser_phantom() {
193193
194194 // The phantom field should be PhantomData<&[i32]> (the DeserType of Vec<i32>)
195195 // We can't directly compare PhantomData types, but we can verify the deserialization worked
196- let _phantom_check: PhantomDeserData < PhantomData < & [ i32 ] > > = eps. phantom ;
196+ let _phantom_check: PhantomDeserData < & [ i32 ] > = eps. phantom ;
197197}
You can’t perform that action at this time.
0 commit comments