Skip to content

Commit 79ec664

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 79ec664

File tree

2 files changed

+111
-18
lines changed

2 files changed

+111
-18
lines changed

src/error.rs

Lines changed: 103 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+
Self { 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+
Self { 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,23 @@ 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)]
556585
pub struct ValidityError<Src, Dst: ?Sized + TryFromBytes> {
557586
/// The source value involved in the conversion.
558587
pub(crate) src: Src,
559588
/// The inner destination type involved in the conversion.
560-
dst: SendSyncPhantomData<Dst>,
589+
_dst: SendSyncPhantomData<Dst>,
590+
}
591+
592+
impl<Src: Clone, Dst: ?Sized + TryFromBytes> Clone for ValidityError<Src, Dst> {
593+
#[inline]
594+
fn clone(&self) -> Self {
595+
Self { src: self.src.clone(), _dst: SendSyncPhantomData::default() }
596+
}
561597
}
562598

563599
impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
564600
pub(crate) fn new(src: Src) -> Self {
565-
Self { src, dst: SendSyncPhantomData::default() }
601+
Self { src, _dst: SendSyncPhantomData::default() }
566602
}
567603

568604
/// Produces the source underlying the failed conversion.
@@ -593,7 +629,7 @@ impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
593629
/// ```
594630
#[inline]
595631
pub fn map_src<NewSrc>(self, f: impl FnOnce(Src) -> NewSrc) -> ValidityError<NewSrc, Dst> {
596-
ValidityError { src: f(self.src), dst: SendSyncPhantomData::default() }
632+
ValidityError { src: f(self.src), _dst: SendSyncPhantomData::default() }
597633
}
598634

599635
/// Converts the error into a general [`ConvertError`].
@@ -614,6 +650,15 @@ impl<Src, Dst: ?Sized + TryFromBytes> ValidityError<Src, Dst> {
614650
}
615651
}
616652

653+
impl<Src: PartialEq, Dst: ?Sized + TryFromBytes> PartialEq for ValidityError<Src, Dst> {
654+
#[inline]
655+
fn eq(&self, other: &Self) -> bool {
656+
self.src == other.src
657+
}
658+
}
659+
660+
impl<Src: Eq, Dst: ?Sized + TryFromBytes> Eq for ValidityError<Src, Dst> {}
661+
617662
impl<Src, Dst: ?Sized + TryFromBytes> fmt::Debug for ValidityError<Src, Dst> {
618663
#[inline]
619664
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -993,6 +1038,48 @@ mod tests {
9931038
}
9941039
}
9951040

1041+
#[test]
1042+
fn test_eq_partial_eq_clone() {
1043+
// Test that all error types implement `Eq`, `PartialEq`
1044+
// and `Clone` if src does
1045+
// even if `Dst: !Eq`, `!PartialEq`, `!Clone`.
1046+
1047+
#[allow(dead_code)]
1048+
fn is_eq_partial_eq_clone<T: Eq + PartialEq + Clone>(_t: T) {}
1049+
1050+
#[allow(dead_code)]
1051+
fn alignment_err_is_eq_partial_eq_clone<Src: Eq + PartialEq + Clone, Dst>(
1052+
err: AlignmentError<Src, Dst>,
1053+
) {
1054+
is_eq_partial_eq_clone(err)
1055+
}
1056+
1057+
#[allow(dead_code)]
1058+
fn size_err_is_eq_partial_eq_clone<Src: Eq + PartialEq + Clone, Dst>(
1059+
err: SizeError<Src, Dst>,
1060+
) {
1061+
is_eq_partial_eq_clone(err)
1062+
}
1063+
1064+
#[allow(dead_code)]
1065+
fn validity_err_is_eq_partial_eq_clone<Src: Eq + PartialEq + Clone, Dst: TryFromBytes>(
1066+
err: ValidityError<Src, Dst>,
1067+
) {
1068+
is_eq_partial_eq_clone(err)
1069+
}
1070+
1071+
#[allow(dead_code)]
1072+
fn convert_error_is_eq_partial_eq_clone<Src: Eq + PartialEq + Clone, Dst: TryFromBytes>(
1073+
err: ConvertError<
1074+
AlignmentError<Src, Dst>,
1075+
SizeError<Src, Dst>,
1076+
ValidityError<Src, Dst>,
1077+
>,
1078+
) {
1079+
is_eq_partial_eq_clone(err)
1080+
}
1081+
}
1082+
9961083
#[test]
9971084
fn alignment_display() {
9981085
#[repr(C, align(128))]

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)