@@ -502,6 +502,160 @@ pub unsafe trait FromBytes: FromZeroes {
502
502
}
503
503
}
504
504
505
+ /// TODO
506
+ pub type AlignedByteArray < T > = Align < ByteArray < T > , T > ;
507
+
508
+ /// A value which might or might not constitute a valid instance of `T`.
509
+ ///
510
+ /// `MaybeValid<T>` has the same layout (size and alignment) and field offsets
511
+ /// as `T`. However, it may contain any bit pattern with a few restrictions:
512
+ /// Given `m: MaybeValid<T>` and a byte offset, `b` in the range `[0,
513
+ /// size_of::<MaybeValid<T>>())`:
514
+ /// - If, in all valid instances `t: T`, the byte at offset `b` in `t` is
515
+ /// initialized, then the byte at offset `b` within `m` is guaranteed to be
516
+ /// initialized.
517
+ /// - Let `s` be the sequence of bytes of length `b` in the offset range `[0,
518
+ /// b)` in `m`. Let `TT` be the subset of valid instances of `T` which contain
519
+ /// this sequence in the offset range `[0, b)`. If, for all instances of `t:
520
+ /// T` in `TT`, the byte at offset `b` in `t` is initialized, then the byte at
521
+ /// offset `b` in `m` is guaranteed to be initialized.
522
+ ///
523
+ /// Pragmatically, this means that if `m` is guaranteed to contain an enum
524
+ /// type at a particular offset, and the enum discriminant stored in `m`
525
+ /// corresponds to a valid variant of that enum type, then it is guaranteed
526
+ /// that the appropriate bytes of `m` are initialized as defined by that
527
+ /// variant's layout (although note that the variant's layout may contain
528
+ /// another enum type, in which case the same rules apply depending on the
529
+ /// state of its discriminant, and so on recursively).
530
+ ///
531
+ /// # Safety
532
+ ///
533
+ /// TODO (make sure to mention enum layout)
534
+ #[ repr( transparent) ]
535
+ pub struct MaybeValid < T > {
536
+ inner : MaybeUninit < T > ,
537
+ }
538
+
539
+ impl < T > MaybeValid < T > {
540
+ /// TODO
541
+ pub const unsafe fn assume_valid ( self ) -> T {
542
+ unsafe { self . inner . assume_init ( ) }
543
+ }
544
+ }
545
+
546
+ unsafe impl < T , F > Projectable < F , MaybeValid < F > > for MaybeValid < T > {
547
+ type Inner = T ;
548
+ }
549
+
550
+ impl < T > From < ByteArray < T > > for MaybeValid < T > {
551
+ fn from ( bytes : ByteArray < T > ) -> MaybeValid < T > {
552
+ todo ! ( )
553
+ }
554
+ }
555
+
556
+ impl < ' a , T > From < & ' a Align < ByteArray < T > , T > > for & ' a MaybeValid < T > {
557
+ fn from ( bytes : & ' a Align < ByteArray < T > , T > ) -> & ' a MaybeValid < T > {
558
+ todo ! ( )
559
+ }
560
+ }
561
+
562
+ impl < ' a , T > From < & ' a mut Align < ByteArray < T > , T > > for & ' a mut MaybeValid < T > {
563
+ fn from ( bytes : & ' a mut Align < ByteArray < T > , T > ) -> & ' a mut MaybeValid < T > {
564
+ todo ! ( )
565
+ }
566
+ }
567
+
568
+ impl < T > Debug for MaybeValid < T > {
569
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
570
+ f. pad ( core:: any:: type_name :: < Self > ( ) )
571
+ }
572
+ }
573
+
574
+ /// TODO
575
+ pub unsafe trait TryFromBytes {
576
+ /// TODO
577
+ fn is_bit_valid ( candidate : & MaybeValid < Self > ) -> bool
578
+ where
579
+ Self : Sized ;
580
+
581
+ /// TODO
582
+ // Note that, in a future in which we distinguish between `FromBytes` and `RefFromBytes`,
583
+ // this requires `where Self: RefFromBytes` to disallow interior mutability.
584
+ fn try_from_ref ( bytes : & [ u8 ] ) -> Option < & Self >
585
+ where
586
+ Self : Sized ,
587
+ {
588
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( bytes) . ok ( ) ?;
589
+ let aligned = Align :: try_from_ref ( byte_array) ?;
590
+
591
+ if Self :: is_bit_valid ( aligned. into ( ) ) {
592
+ Some ( unsafe { & * bytes. as_ptr ( ) . cast :: < Self > ( ) } )
593
+ } else {
594
+ None
595
+ }
596
+ }
597
+
598
+ /// TODO
599
+ fn try_from_mut ( bytes : & mut [ u8 ] ) -> Option < & mut Self >
600
+ where
601
+ Self : AsBytes + Sized ,
602
+ {
603
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( & * bytes) . ok ( ) ?;
604
+ let aligned = Align :: try_from_ref ( byte_array) ?;
605
+
606
+ if Self :: is_bit_valid ( aligned. into ( ) ) {
607
+ Some ( unsafe { & mut * bytes. as_mut_ptr ( ) . cast :: < Self > ( ) } )
608
+ } else {
609
+ None
610
+ }
611
+ }
612
+
613
+ /// TODO
614
+ fn try_read_from ( bytes : & [ u8 ] ) -> Option < Self >
615
+ where
616
+ Self : Sized ,
617
+ {
618
+ let byte_array: & ByteArray < Self > = TryFrom :: try_from ( bytes) . ok ( ) ?;
619
+ let maybe_valid = MaybeValid :: from ( byte_array. clone ( ) ) ;
620
+
621
+ if Self :: is_bit_valid ( & maybe_valid) {
622
+ Some ( unsafe { maybe_valid. assume_valid ( ) } )
623
+ } else {
624
+ None
625
+ }
626
+ }
627
+ }
628
+
629
+ unsafe impl < T : FromBytes > TryFromBytes for T {
630
+ fn is_bit_valid ( _candidate : & MaybeValid < Self > ) -> bool
631
+ where
632
+ Self : Sized ,
633
+ {
634
+ true
635
+ }
636
+ }
637
+
638
+ mod try_from_bytes_derive_example {
639
+ use super :: * ;
640
+
641
+ struct Foo {
642
+ a : u8 ,
643
+ b : u16 ,
644
+ }
645
+
646
+ impl_try_from_bytes ! ( Foo { a: u8 , b: u16 } ) ;
647
+
648
+ struct Bar ( Foo ) ;
649
+
650
+ impl Bar {
651
+ fn is_valid ( & self ) -> bool {
652
+ u16:: from ( self . 0 . a ) < self . 0 . b
653
+ }
654
+ }
655
+
656
+ impl_try_from_bytes ! ( Bar { 0 : Foo } => is_valid) ;
657
+ }
658
+
505
659
/// Types which are safe to treat as an immutable byte slice.
506
660
///
507
661
/// WARNING: Do not implement this trait yourself! Instead, use
@@ -1543,21 +1697,9 @@ impl<T: Display + ?Sized, A> Display for Align<T, A> {
1543
1697
}
1544
1698
}
1545
1699
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
- }
1700
+ // unsafe impl<T: ?Sized, F: ?Sized, A> Projectable<F, Align<F, A>> for Align<T, A> {
1701
+ // type Inner = T;
1702
+ // }
1561
1703
1562
1704
/// A type with no alignment requirement.
1563
1705
///
@@ -2171,18 +2313,9 @@ impl<T> Ord for ByteArray<T> {
2171
2313
}
2172
2314
}
2173
2315
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
- }
2316
+ // unsafe impl<T, F> Projectable<F, ByteArray<F>> for ByteArray<T> {
2317
+ // type Inner = T;
2318
+ // }
2186
2319
2187
2320
// Used in `transmute!` below.
2188
2321
#[ doc( hidden) ]
@@ -3668,6 +3801,21 @@ mod alloc_support {
3668
3801
#[ doc( inline) ]
3669
3802
pub use alloc_support:: * ;
3670
3803
3804
+ /// Transmutes a `T` into a `U`.
3805
+ ///
3806
+ /// # Safety
3807
+ ///
3808
+ /// Safety requirements are the same as for `core::mem::transmute`, except that
3809
+ /// the caller must also ensure that `size_of::<T>() == size_of::<U>()`.
3810
+ unsafe fn transmute_size_unchecked < T , U > ( t : T ) -> U {
3811
+ union Transmute < T , U > {
3812
+ t : ManuallyDrop < T > ,
3813
+ u : ManuallyDrop < U > ,
3814
+ }
3815
+
3816
+ unsafe { ManuallyDrop :: into_inner ( Transmute { t : ManuallyDrop :: new ( t) } . u ) }
3817
+ }
3818
+
3671
3819
#[ cfg( test) ]
3672
3820
mod tests {
3673
3821
#![ allow( clippy:: unreadable_literal) ]
0 commit comments