Skip to content

Commit 1f122e8

Browse files
committed
Fixed tuples, added error for iterator length mismatch
1 parent 2248927 commit 1f122e8

File tree

4 files changed

+49
-20
lines changed

4 files changed

+49
-20
lines changed

CHANGELOG.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44

55
### New
66

7-
* The file format has unfortunately changed. The ReprHash (now AlignHash) of
8-
arrays was wrong and could have led to data corruption. We took this chance
9-
to fix a number of AlignHash implementations.
7+
* The ReprHash (now AlignHash) of arrays was wrong and could have led to data
8+
corruption. As a result, some serialized file might return an alignment
9+
error.
1010

1111
* The implementation for tuples was broken because it assumed that the memory
1212
layout would have been the same of the source layout. We now just support
13-
tuples of zero-copy identical types up to size 12. For the other cases, it is
14-
necessary to create a `repr(C)` tuple newtype.
13+
tuples of zero-copy identical types up to size 12, and `TypeHash` for generic
14+
tuples up to size 12 to help with the idiom `PhantomData<(T, U)>`. For the
15+
other cases, it is necessary to create a `repr(C)` tuple newtype. Note that up
16+
to ε-serde 0.7.0 we provided an erroneous implementation for mixed zero-copy
17+
types. If you serialized a structure using such a tuple, it will be no longer
18+
deserializable.
1519

1620
## [0.7.0] - 2025-02-18
1721

epserde/src/deser/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,9 @@ The serialized type is '{expected_type_name}' and the deserialized type is '{got
385385
got: u64,
386386
},
387387
#[error(
388-
r#"Wrong type repr hash. Expected: 0x{expected:016x} Actual: 0x{got:016x}.
388+
r#"Wrong alignment hash. Expected: 0x{expected:016x} Actual: 0x{got:016x}.
389389
You might be trying to deserialize a file that was serialized on an architecture with different alignment requirements, or some of the fields of the type have changed their copy type (zero or deep).
390+
You might also be trying to deserialize a tuple of mixed zero-copy types, which is no longer supported since 0.8.0, or to deserialize an array, whose alignment hash has been fixed in 0.8.0.
390391
The serialized type is '{expected_type_name}' and the deserialized type is '{got_type_name}'."#
391392
)]
392393
/// The type representation hash is wrong. Probabliy the user is trying to

epserde/src/impls/iter.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ impl<
102102
}
103103

104104
if c != len {
105-
Err(ser::Error::IteratorLengthMismatch { actual: c, expected: len })
105+
Err(ser::Error::IteratorLengthMismatch {
106+
actual: c,
107+
expected: len,
108+
})
106109
} else {
107110
Ok(())
108111
}
@@ -131,10 +134,12 @@ impl<
131134
}
132135

133136
if c != len {
134-
Err(ser::Error::IteratorLengthMismatch { actual: c, expected: len })
137+
Err(ser::Error::IteratorLengthMismatch {
138+
actual: c,
139+
expected: len,
140+
})
135141
} else {
136142
Ok(())
137143
}
138144
}
139145
}
140-

epserde/src/impls/tuple.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,22 @@
1414
//!
1515
//! To circumvent this problem, you can define a tuple newtype with a `repr(C)`
1616
//! attribute.
17-
//!
18-
//! Note that because of this limitation the standard technique of aggregating
19-
//! types in tuples to reduce the number of
20-
//! [`PhantomData`](core::marker::PhantomData) marker should be avoided, unless
21-
//! they are all [`ZeroCopy`].
17+
//!
18+
//! We also provide a [`TypeHash`] implementation for tuples of up to 12
19+
//! elements to help with the idiom `PhantomData<(T1, T2, …)>`.
20+
//!
21+
//! Note that up to ε-serde 0.7.0 we provided an erroneous implementation for
22+
//! mixed zero-copy types. If you serialized a structure using such a tuple,
23+
//! it will be no longer deserializable.
2224
2325
use crate::prelude::*;
2426
use core::hash::Hash;
2527
use deser::*;
2628
use ser::*;
2729

28-
macro_rules! impl_tuples {
30+
macro_rules! impl_type_hash {
2931
($($t:ident),*) => {
30-
impl<T: ZeroCopy> CopyType for ($($t,)*) {
31-
type Copy = Zero;
32-
}
33-
34-
impl<T: TypeHash> TypeHash for ($($t,)*)
32+
impl<$($t: TypeHash,)*> TypeHash for ($($t,)*)
3533
{
3634
#[inline(always)]
3735
fn type_hash(
@@ -43,6 +41,14 @@ macro_rules! impl_tuples {
4341
)*
4442
}
4543
}
44+
}
45+
}
46+
47+
macro_rules! impl_tuples {
48+
($($t:ident),*) => {
49+
impl<T: ZeroCopy> CopyType for ($($t,)*) {
50+
type Copy = Zero;
51+
}
4652

4753
impl<T: AlignHash> AlignHash for ($($t,)*)
4854
{
@@ -107,3 +113,16 @@ macro_rules! impl_tuples_muncher {
107113
}
108114

109115
impl_tuples_muncher!(T, T, T, T, T, T, T, T, T, T, T, T);
116+
117+
macro_rules! impl_type_hash_muncher {
118+
($ty:ident, $($t:ident),*) => {
119+
impl_type_hash!($ty, $($t),*);
120+
impl_type_hash_muncher!($($t),*);
121+
};
122+
($ty:ident) => {
123+
impl_type_hash!($ty);
124+
};
125+
() => {};
126+
}
127+
128+
impl_type_hash_muncher!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);

0 commit comments

Comments
 (0)