@@ -210,6 +210,16 @@ fn check_attrs(input: &DeriveInput) -> (bool, bool, bool) {
210
210
( is_repr_c, is_zero_copy, is_deep_copy)
211
211
}
212
212
213
+ /// Check if a type is PhantomDeserData
214
+ fn is_phantom_deser_data ( ty : & syn:: Type ) -> bool {
215
+ if let syn:: Type :: Path ( type_path) = ty {
216
+ if let Some ( segment) = type_path. path . segments . last ( ) {
217
+ return segment. ident == "PhantomDeserData" ;
218
+ }
219
+ }
220
+ false
221
+ }
222
+
213
223
/// Generate an ε-serde implementation for custom types.
214
224
///
215
225
/// It generates implementations for the traits `CopyType`,
@@ -291,8 +301,9 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
291
301
let mut methods: Vec < proc_macro2:: TokenStream > = vec ! [ ] ;
292
302
293
303
s. fields . iter ( ) . for_each ( |field| {
294
- let ty = & field. ty ;
295
- if generics_names_raw. contains ( & ty. to_token_stream ( ) . to_string ( ) ) {
304
+ if is_phantom_deser_data ( & field. ty ) {
305
+ methods. push ( syn:: parse_quote!( _deserialize_eps_inner_special) ) ;
306
+ } else if generics_names_raw. contains ( & field. ty . to_token_stream ( ) . to_string ( ) ) {
296
307
methods. push ( syn:: parse_quote!( _deserialize_eps_inner) ) ;
297
308
} else {
298
309
methods. push ( syn:: parse_quote!( _deserialize_full_inner) ) ;
@@ -369,62 +380,11 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
369
380
} )
370
381
. collect :: < Vec < _ > > ( ) ;
371
382
372
- // If there are bounded type parameters which are fields of the
373
- // struct, we need to impose the same bounds on the SerType and on
374
- // the DeserType.
375
- derive_input. generics . params . iter ( ) . for_each ( |param| {
376
- if let GenericParam :: Type ( t) = param {
377
- let ty = & t. ident ;
378
-
379
- // We are just interested in types with bounds that are
380
- // types of fields of the struct.
381
- //
382
- // Note that types_with_generics contains also field types
383
- // *containing* a type parameter, but that just slows down
384
- // the search.
385
- if ! t. bounds . is_empty ( ) &&
386
- types_with_generics. iter ( ) . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) ) {
387
-
388
- // Add a lifetime so we express bounds on DeserType
389
- let mut lifetimes = Punctuated :: new ( ) ;
390
- lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
391
- attrs : vec ! [ ] ,
392
- lifetime : syn:: Lifetime :: new ( "'epserde_desertype" , proc_macro2:: Span :: call_site ( ) ) ,
393
- colon_token : None ,
394
- bounds : Punctuated :: new ( ) ,
395
- } ) ) ;
396
- // Add the type bounds to the DeserType
397
- where_clause_des
398
- . predicates
399
- . push ( WherePredicate :: Type ( PredicateType {
400
- lifetimes : Some ( BoundLifetimes {
401
- for_token : token:: For :: default ( ) ,
402
- lt_token : token:: Lt :: default ( ) ,
403
- lifetimes,
404
- gt_token : token:: Gt :: default ( ) ,
405
- } ) ,
406
- bounded_ty : syn:: parse_quote!(
407
- <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
408
- ) ,
409
- colon_token : token:: Colon :: default ( ) ,
410
- bounds : t. bounds . clone ( ) ,
411
- } ) ) ;
412
- // Add the type bounds to the SerType
413
- where_clause_ser
414
- . predicates
415
- . push ( WherePredicate :: Type ( PredicateType {
416
- lifetimes : None ,
417
- bounded_ty : syn:: parse_quote!(
418
- <#ty as epserde:: ser:: SerializeInner >:: SerType
419
- ) ,
420
- colon_token : token:: Colon :: default ( ) ,
421
- bounds : t. bounds . clone ( ) ,
422
- } ) ) ;
423
- }
424
- }
425
- } ) ;
426
-
427
383
if is_zero_copy {
384
+ // In zero-copy types we do not need to add bounds to
385
+ // the associated SerType/DeserType, as generics are not
386
+ // replaced with their SerType/DeserType.
387
+
428
388
quote ! {
429
389
#[ automatically_derived]
430
390
impl <#impl_generics> epserde:: traits:: CopyType for #name<#concat_generics> #where_clause {
@@ -433,7 +393,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
433
393
434
394
#[ automatically_derived]
435
395
impl <#generics_serialize> epserde:: ser:: SerializeInner for #name<#concat_generics> #where_clause_ser {
436
- type SerType = #name<# ( #ser_type_generics ) , * > ;
396
+ type SerType = Self ;
437
397
// Compute whether the type could be zero copy
438
398
const IS_ZERO_COPY : bool = #is_repr_c #(
439
399
&& <#fields_types>:: IS_ZERO_COPY
@@ -463,7 +423,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
463
423
epserde:: deser:: helpers:: deserialize_full_zero:: <Self >( backend)
464
424
}
465
425
466
- type DeserType <' epserde_desertype> = & ' epserde_desertype #name<#concat_generics> ;
426
+ type DeserType <' epserde_desertype> = & ' epserde_desertype Self ;
467
427
468
428
unsafe fn _deserialize_eps_inner<' deserialize_eps_inner_lifetime>(
469
429
backend: & mut epserde:: deser:: SliceWithPos <' deserialize_eps_inner_lifetime>,
@@ -474,6 +434,62 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
474
434
}
475
435
}
476
436
} else {
437
+ // If there are bounded type parameters which are fields of the
438
+ // struct, we need to impose the same bounds on the SerType and on
439
+ // the DeserType.
440
+ derive_input. generics . params . iter ( ) . for_each ( |param| {
441
+ if let GenericParam :: Type ( t) = param {
442
+ let ty = & t. ident ;
443
+
444
+ // We are just interested in types with bounds that are
445
+ // types of fields of the struct.
446
+ //
447
+ // Note that types_with_generics contains also field types
448
+ // *containing* a type parameter, but that just slows down
449
+ // the search.
450
+ if ! t. bounds . is_empty ( ) &&
451
+ types_with_generics. iter ( ) . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) ) {
452
+
453
+ let mut lifetimes = Punctuated :: new ( ) ;
454
+ // Add a lifetime so we express bounds on DeserType
455
+ lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
456
+ attrs : vec ! [ ] ,
457
+ lifetime : syn:: Lifetime :: new ( "'epserde_desertype" , proc_macro2:: Span :: call_site ( ) ) ,
458
+ colon_token : None ,
459
+ bounds : Punctuated :: new ( ) ,
460
+ } ) ) ;
461
+ // Add the type bounds to the DeserType
462
+ where_clause_des
463
+ . predicates
464
+ . push ( WherePredicate :: Type ( PredicateType {
465
+ lifetimes : Some ( BoundLifetimes {
466
+ for_token : token:: For :: default ( ) ,
467
+ lt_token : token:: Lt :: default ( ) ,
468
+ lifetimes,
469
+ gt_token : token:: Gt :: default ( ) ,
470
+ } ) ,
471
+ bounded_ty : syn:: parse_quote!(
472
+ <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
473
+ ) ,
474
+ colon_token : token:: Colon :: default ( ) ,
475
+ bounds : t. bounds . clone ( ) ,
476
+ } ) ) ;
477
+
478
+ // Add the type bounds to the SerType
479
+ where_clause_ser
480
+ . predicates
481
+ . push ( WherePredicate :: Type ( PredicateType {
482
+ lifetimes : None ,
483
+ bounded_ty : syn:: parse_quote!(
484
+ <#ty as epserde:: ser:: SerializeInner >:: SerType
485
+ ) ,
486
+ colon_token : token:: Colon :: default ( ) ,
487
+ bounds : t. bounds . clone ( ) ,
488
+ } ) ) ;
489
+ }
490
+ }
491
+ } ) ;
492
+
477
493
quote ! {
478
494
#[ automatically_derived]
479
495
impl <#impl_generics> epserde:: traits:: CopyType for #name<#concat_generics> #where_clause {
@@ -608,7 +624,9 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
608
624
bounds : bounds_des,
609
625
} ) ) ;
610
626
611
- if generics_names_raw. contains ( & ty. to_token_stream ( ) . to_string ( ) ) {
627
+ if is_phantom_deser_data ( & ty) {
628
+ methods. push ( syn:: parse_quote!( _deserialize_eps_inner_special) ) ;
629
+ } else if generics_names_raw. contains ( & ty. to_token_stream ( ) . to_string ( ) ) {
612
630
methods. push ( syn:: parse_quote!( _deserialize_eps_inner) ) ;
613
631
} else {
614
632
methods. push ( syn:: parse_quote!( _deserialize_full_inner) ) ;
@@ -760,7 +778,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
760
778
}
761
779
#[ automatically_derived]
762
780
impl <#generics_serialize> epserde:: ser:: SerializeInner for #name<#concat_generics> #where_clause_ser {
763
- type SerType = #name<# ( #ser_type_generics , ) * > ;
781
+ type SerType = Self ;
764
782
765
783
// Compute whether the type could be zero copy
766
784
const IS_ZERO_COPY : bool = #is_repr_c #(
@@ -788,7 +806,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
788
806
epserde:: deser:: helpers:: deserialize_full_zero:: <Self >( backend)
789
807
}
790
808
791
- type DeserType <' epserde_desertype> = & ' epserde_desertype #name<#concat_generics> ;
809
+ type DeserType <' epserde_desertype> = & ' epserde_desertype Self ;
792
810
793
811
unsafe fn _deserialize_eps_inner<' deserialize_eps_inner_lifetime>(
794
812
backend: & mut epserde:: deser:: SliceWithPos <' deserialize_eps_inner_lifetime>,
@@ -799,6 +817,62 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
799
817
}
800
818
}
801
819
} else {
820
+ // If there are bounded type parameters which are fields of the
821
+ // struct, we need to impose the same bounds on the SerType and on
822
+ // the DeserType.
823
+ derive_input. generics . params . iter ( ) . for_each ( |param| {
824
+ if let GenericParam :: Type ( t) = param {
825
+ let ty = & t. ident ;
826
+
827
+ // We are just interested in types with bounds that are
828
+ // types of fields of the struct.
829
+ //
830
+ // Note that types_with_generics contains also field types
831
+ // *containing* a type parameter, but that just slows down
832
+ // the search.
833
+ if ! t. bounds . is_empty ( ) &&
834
+ types_with_generics. iter ( ) . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) ) {
835
+
836
+ let mut lifetimes = Punctuated :: new ( ) ;
837
+ // Add a lifetime so we express bounds on DeserType
838
+ lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
839
+ attrs : vec ! [ ] ,
840
+ lifetime : syn:: Lifetime :: new ( "'epserde_desertype" , proc_macro2:: Span :: call_site ( ) ) ,
841
+ colon_token : None ,
842
+ bounds : Punctuated :: new ( ) ,
843
+ } ) ) ;
844
+ // Add the type bounds to the DeserType
845
+ where_clause_des
846
+ . predicates
847
+ . push ( WherePredicate :: Type ( PredicateType {
848
+ lifetimes : Some ( BoundLifetimes {
849
+ for_token : token:: For :: default ( ) ,
850
+ lt_token : token:: Lt :: default ( ) ,
851
+ lifetimes,
852
+ gt_token : token:: Gt :: default ( ) ,
853
+ } ) ,
854
+ bounded_ty : syn:: parse_quote!(
855
+ <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
856
+ ) ,
857
+ colon_token : token:: Colon :: default ( ) ,
858
+ bounds : t. bounds . clone ( ) ,
859
+ } ) ) ;
860
+
861
+ // Add the type bounds to the SerType
862
+ where_clause_ser
863
+ . predicates
864
+ . push ( WherePredicate :: Type ( PredicateType {
865
+ lifetimes : None ,
866
+ bounded_ty : syn:: parse_quote!(
867
+ <#ty as epserde:: ser:: SerializeInner >:: SerType
868
+ ) ,
869
+ colon_token : token:: Colon :: default ( ) ,
870
+ bounds : t. bounds . clone ( ) ,
871
+ } ) ) ;
872
+ }
873
+ }
874
+ } ) ;
875
+
802
876
quote ! {
803
877
#[ automatically_derived]
804
878
impl <#impl_generics> epserde:: traits:: CopyType for #name<#concat_generics> #where_clause {
0 commit comments