@@ -502,6 +502,98 @@ pub unsafe trait FromBytes: FromZeroes {
502
502
}
503
503
}
504
504
505
+ /// TODO
506
+ pub type AlignedByteArray < T > = Align < ByteArray < T > , T > ;
507
+
508
+ unsafe impl < T , F > Projectable < F , AlignedByteArray < F > > for AlignedByteArray < T > {
509
+ type Inner = T ;
510
+ }
511
+
512
+ /// TODO
513
+ pub unsafe trait TryFromBytes {
514
+ /// TODO
515
+ fn is_bit_valid ( bytes : & AlignedByteArray < Self > ) -> bool
516
+ where
517
+ Self : Sized ;
518
+
519
+ /// TODO
520
+ // Note that, in a future in which we distinguish between `FromBytes` and `RefFromBytes`,
521
+ // this requires `where Self: RefFromBytes` to disallow interior mutability.
522
+ fn try_from_ref ( bytes : & [ u8 ] ) -> Option < & Self >
523
+ where
524
+ Self : Sized ,
525
+ {
526
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( bytes) . ok ( ) ?;
527
+ let aligned = Align :: try_from_ref ( byte_array) ?;
528
+
529
+ if Self :: is_bit_valid ( aligned) {
530
+ Some ( unsafe { & * bytes. as_ptr ( ) . cast :: < Self > ( ) } )
531
+ } else {
532
+ None
533
+ }
534
+ }
535
+
536
+ /// TODO
537
+ fn try_from_mut ( bytes : & mut [ u8 ] ) -> Option < & mut Self >
538
+ where
539
+ Self : AsBytes + Sized ,
540
+ {
541
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( & * bytes) . ok ( ) ?;
542
+ let aligned = Align :: try_from_ref ( byte_array) ?;
543
+
544
+ if Self :: is_bit_valid ( aligned) {
545
+ Some ( unsafe { & mut * bytes. as_mut_ptr ( ) . cast :: < Self > ( ) } )
546
+ } else {
547
+ None
548
+ }
549
+ }
550
+
551
+ /// TODO
552
+ fn try_read_from ( bytes : & [ u8 ] ) -> Option < Self >
553
+ where
554
+ Self : Sized ,
555
+ {
556
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( bytes) . ok ( ) ?;
557
+ let aligned = Align :: new ( byte_array. clone ( ) ) ;
558
+
559
+ if Self :: is_bit_valid ( & aligned) {
560
+ Some ( unsafe { transmute_size_unchecked ( aligned) } )
561
+ } else {
562
+ None
563
+ }
564
+ }
565
+ }
566
+
567
+ unsafe impl < T : FromBytes > TryFromBytes for T {
568
+ fn is_bit_valid ( _bytes : & AlignedByteArray < Self > ) -> bool
569
+ where
570
+ Self : Sized ,
571
+ {
572
+ true
573
+ }
574
+ }
575
+
576
+ mod try_from_bytes_derive_example {
577
+ use super :: * ;
578
+
579
+ struct Foo {
580
+ a : u8 ,
581
+ b : u16 ,
582
+ }
583
+
584
+ impl_try_from_bytes ! ( Foo { a: u8 , b: u16 } ) ;
585
+
586
+ struct Bar ( Foo ) ;
587
+
588
+ impl Bar {
589
+ fn is_valid ( & self ) -> bool {
590
+ u16:: from ( self . 0 . a ) < self . 0 . b
591
+ }
592
+ }
593
+
594
+ impl_try_from_bytes ! ( Bar { 0 : Foo } => is_valid) ;
595
+ }
596
+
505
597
/// Types which are safe to treat as an immutable byte slice.
506
598
///
507
599
/// WARNING: Do not implement this trait yourself! Instead, use
@@ -1543,21 +1635,9 @@ impl<T: Display + ?Sized, A> Display for Align<T, A> {
1543
1635
}
1544
1636
}
1545
1637
1546
- unsafe impl < T : ?Sized , A > Projectable for Align < T , A > {
1547
- type Inner = T ;
1548
- // SAFETY: We know that `U` can't be more aligned than `T` or else it
1549
- // couldn't be a field in `T`. Thus, any `U` within `Align<T, A>` is already
1550
- // aligned to `max(align_of::<U>(), align_of::<A>())`.
1551
- type Wrapped < U > = Align < U , A > ;
1552
-
1553
- fn foo ( & self ) -> * const T {
1554
- self as * const Self as * const T
1555
- }
1556
-
1557
- fn foo_mut ( & mut self ) -> * mut T {
1558
- self as * mut Self as * mut T
1559
- }
1560
- }
1638
+ // unsafe impl<T: ?Sized, F: ?Sized, A> Projectable<F, Align<F, A>> for Align<T, A> {
1639
+ // type Inner = T;
1640
+ // }
1561
1641
1562
1642
/// A type with no alignment requirement.
1563
1643
///
@@ -2171,18 +2251,9 @@ impl<T> Ord for ByteArray<T> {
2171
2251
}
2172
2252
}
2173
2253
2174
- unsafe impl < T > Projectable for ByteArray < T > {
2175
- type Inner = T ;
2176
- type Wrapped < U > = ByteArray < U > ;
2177
-
2178
- fn foo ( & self ) -> * const T {
2179
- self as * const Self as * const T
2180
- }
2181
-
2182
- fn foo_mut ( & mut self ) -> * mut T {
2183
- self as * mut Self as * mut T
2184
- }
2185
- }
2254
+ // unsafe impl<T, F> Projectable<F, ByteArray<F>> for ByteArray<T> {
2255
+ // type Inner = T;
2256
+ // }
2186
2257
2187
2258
// Used in `transmute!` below.
2188
2259
#[ doc( hidden) ]
@@ -3668,6 +3739,21 @@ mod alloc_support {
3668
3739
#[ doc( inline) ]
3669
3740
pub use alloc_support:: * ;
3670
3741
3742
+ /// Transmutes a `T` into a `U`.
3743
+ ///
3744
+ /// # Safety
3745
+ ///
3746
+ /// Safety requirements are the same as for `core::mem::transmute`, except that
3747
+ /// the caller must also ensure that `size_of::<T>() == size_of::<U>()`.
3748
+ unsafe fn transmute_size_unchecked < T , U > ( t : T ) -> U {
3749
+ union Transmute < T , U > {
3750
+ t : ManuallyDrop < T > ,
3751
+ u : ManuallyDrop < U > ,
3752
+ }
3753
+
3754
+ unsafe { ManuallyDrop :: into_inner ( Transmute { t : ManuallyDrop :: new ( t) } . u ) }
3755
+ }
3756
+
3671
3757
#[ cfg( test) ]
3672
3758
mod tests {
3673
3759
#![ allow( clippy:: unreadable_literal) ]
0 commit comments