Skip to content

Commit f43f9fc

Browse files
committed
Documentation for PhantomDeserData
1 parent 092aa73 commit f43f9fc

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ These are the main limitations you should be aware of before choosing to use
108108
generated at deserialization time is stored in newly allocated memory. This is
109109
not the case with [Abomonation].
110110

111-
## Example: Zero copy of standard types
111+
## Example: Zero-copy of standard types
112112

113113
Let us start with the simplest case: data that can be zero-copy deserialized. In
114114
this case, we serialize an array of a thousand zeros, and get back a reference
@@ -664,6 +664,17 @@ the hood because `BitFieldVec` is ε-serde-aware, and in fact you will not even
664664
notice the difference if you access both versions using the trait
665665
`BitFieldSlice`.
666666

667+
## [`PhantomData`]
668+
669+
[`PhantomData`] undergoes a special treatment: its type parameter `T` does not
670+
have to be (de)serializable or sized—it is sufficient that it implements
671+
[`TypeHash`]. Moreover, `T` is not replaced with its associated
672+
(de)serialization type.
673+
674+
There might be corner cases in which `T` appears both as a parameter of
675+
[`PhantomData`] and as a type parameter of a field of a type. In this case, you
676+
can use [`PhantomDeserData`] instead of [`PhantomData`].
677+
667678
## MemDbg / MemSize
668679

669680
All ε-serde structures implement the [`MemDbg`] and [`MemSize`] traits.
@@ -723,3 +734,4 @@ European Union nor the Italian MUR can be held responsible for them.
723734
[`PhantomData`]: <https://doc.rust-lang.org/std/marker/struct.PhantomData.html>
724735
[`Iterator`]: <https://doc.rust-lang.org/std/iter/trait.Iterator.html>
725736
[`SerIter`]: <https://docs.rs/epserde/latest/epserde/impls/iter/struct.SerIter.html>
737+
[`PhantomDeserData`]: <https://docs.rs/epserde/latest/epserde/struct.PhantomDeserData.html>

epserde-derive/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,10 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
793793
let tag = (0..variants.len()).collect::<Vec<_>>();
794794

795795
if is_zero_copy {
796+
// In zero-copy types we do not need to add bounds to
797+
// the associated SerType/DeserType, as generics are not
798+
// replaced with their SerType/DeserType.
799+
796800
quote! {
797801
#[automatically_derived]
798802
impl<#impl_generics> epserde::traits::CopyType for #name<#concat_generics> #where_clause {

epserde/src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub mod prelude {
4545
pub use crate::ser::SerializeInner;
4646
pub use crate::traits::*;
4747
pub use crate::utils::*;
48+
pub use crate::PhantomDeserData;
4849
#[cfg(feature = "derive")]
4950
pub use epserde_derive::Epserde;
5051
}
@@ -63,6 +64,37 @@ pub fn pad_align_to(value: usize, align_to: usize) -> usize {
6364
value.wrapping_neg() & (align_to - 1)
6465
}
6566

67+
/// A type semantically equivalent to [`PhantomData`], but whose type parameter
68+
/// is replaced with its associated deserialization type.
69+
///
70+
/// In some case, you might find yourself with a deep-copy type that has a type
71+
/// parameter `T` appearing both in a field and in a [`PhantomData`]. In this
72+
/// case, the type will not compile, as in its associated deserialization type
73+
/// `T` will be replaced by `T::DeserType`, but the [`PhantomData`] field will
74+
/// still contain `T`. To fix this issue, you can use [`PhantomDeserData`]
75+
/// instead.
76+
///
77+
/// # Examples
78+
///
79+
/// This code will not compile:
80+
/// ```compile_fail
81+
/// use epserde::prelude::*;
82+
/// #[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
83+
/// struct Data<T> {
84+
/// data: T,
85+
/// phantom: PhantomData<T>,
86+
/// }
87+
/// ```
88+
///
89+
/// This code, instead, will compile:
90+
/// ```
91+
/// use epserde::prelude::*;
92+
/// #[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
93+
/// struct Data<T> {
94+
/// data: T,
95+
/// phantom: PhantomDeserData<T>,
96+
/// }
97+
/// ```
6698
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
6799
pub struct PhantomDeserData<T: ?Sized>(pub PhantomData<T>);
68100

0 commit comments

Comments
 (0)