Skip to content

Commit cd391b4

Browse files
committed
Make errors Clone.
Manually implement PartialEq, Eq and Clone for types using SendSyncPhantomData. This is necessary because the default derive imposes an additional PartialEq/Eq/Clone bounds on the phantom type.
1 parent 846c36e commit cd391b4

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

src/error.rs

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ use crate::{FromBytes, Ref};
149149
/// - [`CastError`]: the error type of reference conversions
150150
/// - [`TryCastError`]: the error type of fallible reference conversions
151151
/// - [`TryReadError`]: the error type of fallible read conversions
152-
#[derive(PartialEq, Eq)]
152+
#[derive(PartialEq, Eq, Clone)]
153153
pub enum ConvertError<A, S, V> {
154154
/// The conversion source was improperly aligned.
155155
Alignment(A),
@@ -242,15 +242,14 @@ where
242242
}
243243

244244
/// The error emitted if the conversion source is improperly aligned.
245-
#[derive(PartialEq, Eq)]
246245
pub struct AlignmentError<Src, Dst: ?Sized> {
247246
/// The source value involved in the conversion.
248247
src: Src,
249248
/// The inner destination type involved in the conversion.
250249
///
251250
/// INVARIANT: An `AlignmentError` may only be constructed if `Dst`'s
252251
/// alignment requirement is greater than one.
253-
dst: SendSyncPhantomData<Dst>,
252+
_dst: SendSyncPhantomData<Dst>,
254253
}
255254

256255
impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
@@ -261,7 +260,7 @@ impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
261260
pub(crate) unsafe fn new_unchecked(src: Src) -> Self {
262261
// INVARIANT: The caller guarantees that `Dst`'s alignment requirement
263262
// is greater than one.
264-
Self { src, dst: SendSyncPhantomData::default() }
263+
Self { src, _dst: SendSyncPhantomData::default() }
265264
}
266265

267266
/// Produces the source underlying the failed conversion.
@@ -274,7 +273,7 @@ impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
274273
// INVARIANT: `with_src` doesn't change the type of `Dst`, so the
275274
// invariant that `Dst`'s alignment requirement is greater than one is
276275
// preserved.
277-
AlignmentError { src: new_src, dst: SendSyncPhantomData::default() }
276+
AlignmentError { src: new_src, _dst: SendSyncPhantomData::default() }
278277
}
279278

280279
/// Maps the source value associated with the conversion error.
@@ -299,7 +298,7 @@ impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
299298
/// ```
300299
#[inline]
301300
pub fn map_src<NewSrc>(self, f: impl FnOnce(Src) -> NewSrc) -> AlignmentError<NewSrc, Dst> {
302-
AlignmentError { src: f(self.src), dst: SendSyncPhantomData::default() }
301+
AlignmentError { src: f(self.src), _dst: SendSyncPhantomData::default() }
303302
}
304303

305304
pub(crate) fn into<S, V>(self) -> ConvertError<Self, S, V> {
@@ -337,6 +336,22 @@ impl<Src, Dst: ?Sized> AlignmentError<Src, Dst> {
337336
}
338337
}
339338

339+
impl<Src: Clone, Dst: ?Sized> Clone for AlignmentError<Src, Dst> {
340+
#[inline]
341+
fn clone(&self) -> Self {
342+
AlignmentError { src: self.src.clone(), _dst: SendSyncPhantomData::default() }
343+
}
344+
}
345+
346+
impl<Src: PartialEq, Dst: ?Sized> PartialEq for AlignmentError<Src, Dst> {
347+
#[inline]
348+
fn eq(&self, other: &Self) -> bool {
349+
self.src == other.src
350+
}
351+
}
352+
353+
impl<Src: Eq, Dst: ?Sized> Eq for AlignmentError<Src, Dst> {}
354+
340355
impl<Src, Dst: ?Sized + Unaligned> From<AlignmentError<Src, Dst>> for Infallible {
341356
#[inline(always)]
342357
fn from(_: AlignmentError<Src, Dst>) -> Infallible {
@@ -408,17 +423,16 @@ impl<Src, Dst: ?Sized, S, V> From<AlignmentError<Src, Dst>>
408423
}
409424

410425
/// The error emitted if the conversion source is of incorrect size.
411-
#[derive(PartialEq, Eq)]
412426
pub struct SizeError<Src, Dst: ?Sized> {
413427
/// The source value involved in the conversion.
414428
src: Src,
415429
/// The inner destination type involved in the conversion.
416-
dst: SendSyncPhantomData<Dst>,
430+
_dst: SendSyncPhantomData<Dst>,
417431
}
418432

419433
impl<Src, Dst: ?Sized> SizeError<Src, Dst> {
420434
pub(crate) fn new(src: Src) -> Self {
421-
Self { src, dst: SendSyncPhantomData::default() }
435+
Self { src, _dst: SendSyncPhantomData::default() }
422436
}
423437

424438
/// Produces the source underlying the failed conversion.
@@ -429,7 +443,7 @@ impl<Src, Dst: ?Sized> SizeError<Src, Dst> {
429443

430444
/// Sets the source value associated with the conversion error.
431445
pub(crate) fn with_src<NewSrc>(self, new_src: NewSrc) -> SizeError<NewSrc, Dst> {
432-
SizeError { src: new_src, dst: SendSyncPhantomData::default() }
446+
SizeError { src: new_src, _dst: SendSyncPhantomData::default() }
433447
}
434448

435449
/// Maps the source value associated with the conversion error.
@@ -455,12 +469,12 @@ impl<Src, Dst: ?Sized> SizeError<Src, Dst> {
455469
/// ```
456470
#[inline]
457471
pub fn map_src<NewSrc>(self, f: impl FnOnce(Src) -> NewSrc) -> SizeError<NewSrc, Dst> {
458-
SizeError { src: f(self.src), dst: SendSyncPhantomData::default() }
472+
SizeError { src: f(self.src), _dst: SendSyncPhantomData::default() }
459473
}
460474

461475
/// Sets the destination type associated with the conversion error.
462476
pub(crate) fn with_dst<NewDst: ?Sized>(self) -> SizeError<Src, NewDst> {
463-
SizeError { src: self.src, dst: SendSyncPhantomData::default() }
477+
SizeError { src: self.src, _dst: SendSyncPhantomData::default() }
464478
}
465479

466480
/// Converts the error into a general [`ConvertError`].
@@ -507,6 +521,22 @@ impl<Src, Dst: ?Sized> SizeError<Src, Dst> {
507521
}
508522
}
509523

524+
impl<Src: Clone, Dst: ?Sized> Clone for SizeError<Src, Dst> {
525+
#[inline]
526+
fn clone(&self) -> Self {
527+
SizeError { src: self.src.clone(), _dst: SendSyncPhantomData::default() }
528+
}
529+
}
530+
531+
impl<Src: PartialEq, Dst: ?Sized> PartialEq for SizeError<Src, Dst> {
532+
#[inline]
533+
fn eq(&self, other: &Self) -> bool {
534+
self.src == other.src
535+
}
536+
}
537+
538+
impl<Src: Eq, Dst: ?Sized> Eq for SizeError<Src, Dst> {}
539+
510540
impl<Src, Dst: ?Sized> fmt::Debug for SizeError<Src, Dst> {
511541
#[inline]
512542
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -552,17 +582,17 @@ impl<Src, Dst: ?Sized, A, V> From<SizeError<Src, Dst>> for ConvertError<A, SizeE
552582
}
553583

554584
/// The error emitted if the conversion source contains invalid data.
555-
#[derive(PartialEq, Eq)]
585+
#[derive(Eq)]
556586
pub struct ValidityError<Src, Dst: ?Sized + TryFromBytes> {
557587
/// The source value involved in the conversion.
558588
pub(crate) src: Src,
559589
/// The inner destination type involved in the conversion.
560-
dst: SendSyncPhantomData<Dst>,
590+
_dst: SendSyncPhantomData<Dst>,
561591
}
562592

563593
impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
564594
pub(crate) fn new(src: Src) -> Self {
565-
Self { src, dst: SendSyncPhantomData::default() }
595+
Self { src, _dst: SendSyncPhantomData::default() }
566596
}
567597

568598
/// Produces the source underlying the failed conversion.
@@ -593,7 +623,7 @@ impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
593623
/// ```
594624
#[inline]
595625
pub fn map_src<NewSrc>(self, f: impl FnOnce(Src) -> NewSrc) -> ValidityError<NewSrc, Dst> {
596-
ValidityError { src: f(self.src), dst: SendSyncPhantomData::default() }
626+
ValidityError { src: f(self.src), _dst: SendSyncPhantomData::default() }
597627
}
598628

599629
/// Converts the error into a general [`ConvertError`].
@@ -614,6 +644,13 @@ impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
614644
}
615645
}
616646

647+
impl<Src: PartialEq, Dst: ?Sized + TryFromBytes> PartialEq for ValidityError<Src, Dst> {
648+
#[inline]
649+
fn eq(&self, other: &Self) -> bool {
650+
self.src == other.src
651+
}
652+
}
653+
617654
impl<Src, Dst: ?Sized + TryFromBytes> fmt::Debug for ValidityError<Src, Dst> {
618655
#[inline]
619656
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1078,4 +1115,13 @@ mod tests {
10781115
Destination type: bool"
10791116
);
10801117
}
1118+
1119+
/// A dummy type with no traits implemented.
1120+
struct NoTraits;
1121+
1122+
#[test]
1123+
fn clone_size_error() {
1124+
let err = SizeError::<_, NoTraits>::new(&NoTraits);
1125+
let _err2 = err.clone();
1126+
}
10811127
}

src/util/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,19 @@ impl<T: ?Sized> Default for SendSyncPhantomData<T> {
3939
}
4040

4141
impl<T: ?Sized> PartialEq for SendSyncPhantomData<T> {
42-
fn eq(&self, other: &Self) -> bool {
43-
self.0.eq(&other.0)
42+
fn eq(&self, _other: &Self) -> bool {
43+
true
4444
}
4545
}
4646

4747
impl<T: ?Sized> Eq for SendSyncPhantomData<T> {}
4848

49+
impl<T: ?Sized> Clone for SendSyncPhantomData<T> {
50+
fn clone(&self) -> Self {
51+
SendSyncPhantomData(PhantomData)
52+
}
53+
}
54+
4955
pub(crate) trait AsAddress {
5056
fn addr(self) -> usize;
5157
}

0 commit comments

Comments
 (0)