@@ -387,7 +387,7 @@ use core::alloc::Layout;
387
387
388
388
// Used by `TryFromBytes::is_bit_valid`.
389
389
#[ doc( hidden) ]
390
- pub use crate :: pointer:: { invariant:: BecauseImmutable , Maybe , MaybeAligned , Ptr } ;
390
+ pub use crate :: pointer:: { invariant:: BecauseImmutable , Maybe , Ptr } ;
391
391
// Used by `KnownLayout`.
392
392
#[ doc( hidden) ]
393
393
pub use crate :: layout:: * ;
@@ -805,6 +805,17 @@ pub unsafe trait KnownLayout {
805
805
// resulting size would not fit in a `usize`.
806
806
meta. size_for_metadata ( Self :: LAYOUT )
807
807
}
808
+
809
+ #[ doc( hidden) ]
810
+ #[ must_use]
811
+ #[ inline( always) ]
812
+ fn cast_from_raw < P : KnownLayout < PointerMetadata = Self :: PointerMetadata > + ?Sized > (
813
+ ptr : NonNull < P > ,
814
+ ) -> NonNull < Self > {
815
+ let data = ptr. cast :: < u8 > ( ) ;
816
+ let meta = P :: pointer_to_metadata ( ptr. as_ptr ( ) ) ;
817
+ Self :: raw_from_ptr_len ( data, meta)
818
+ }
808
819
}
809
820
810
821
/// The metadata associated with a [`KnownLayout`] type.
@@ -2843,29 +2854,43 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
2843
2854
// We use `from_mut` despite not mutating via `c_ptr` so that we don't need
2844
2855
// to add a `T: Immutable` bound.
2845
2856
let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2846
- let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
2847
2857
// SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
2848
2858
// `candidate`, which the caller promises is entirely initialized. Since
2849
2859
// `candidate` is a `MaybeUninit`, it has no validity requirements, and so
2850
- // no values written to ` c_ptr` can violate its validity. Since `c_ptr` has
2851
- // ` Exclusive` aliasing, no mutations may happen except via `c_ptr` so long
2852
- // as it is live, so we don't need to worry about the fact that `c_ptr` may
2853
- // have more restricted validity than `candidate`.
2860
+ // no values written to an `Initialized` ` c_ptr` can violate its validity.
2861
+ // Since `c_ptr` has ` Exclusive` aliasing, no mutations may happen except
2862
+ // via `c_ptr` so long as it is live, so we don't need to worry about the
2863
+ // fact that `c_ptr` may have more restricted validity than `candidate`.
2854
2864
let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2865
+ let c_ptr = c_ptr. transmute ( ) ;
2855
2866
2867
+ // Since we don't have `T: KnownLayout`, we hack around that by using
2868
+ // `Wrapping<T>`, which implements `KnownLayout` even if `T` doesn't.
2869
+ //
2856
2870
// This call may panic. If that happens, it doesn't cause any soundness
2857
- // issues, as we have not generated any invalid state which we need to
2858
- // fix before returning.
2871
+ // issues, as we have not generated any invalid state which we need to fix
2872
+ // before returning.
2859
2873
//
2860
- // Note that one panic or post-monomorphization error condition is
2861
- // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2862
- // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2863
- // condition will not happen.
2864
- if !T :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2874
+ // Note that one panic or post-monomorphization error condition is calling
2875
+ // `try_into_valid` (and thus `is_bit_valid`) with a shared pointer when
2876
+ // `Self: !Immutable`. Since `Self: Immutable`, this panic condition will
2877
+ // not happen.
2878
+ if !Wrapping :: < T > :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2865
2879
return Err ( ValidityError :: new ( source) . into ( ) ) ;
2866
2880
}
2867
2881
2868
- // SAFETY: We just validated that `candidate` contains a valid `T`.
2882
+ fn _assert_same_size_and_validity < T > ( )
2883
+ where
2884
+ Wrapping < T > : pointer:: TransmuteFrom < T , invariant:: Valid , invariant:: Valid > ,
2885
+ T : pointer:: TransmuteFrom < Wrapping < T > , invariant:: Valid , invariant:: Valid > ,
2886
+ {
2887
+ }
2888
+
2889
+ _assert_same_size_and_validity :: < T > ( ) ;
2890
+
2891
+ // SAFETY: We just validated that `candidate` contains a valid
2892
+ // `Wrapping<T>`, which has the same size and bit validity as `T`, as
2893
+ // guaranteed by the preceding type assertion.
2869
2894
Ok ( unsafe { candidate. assume_init ( ) } )
2870
2895
}
2871
2896
@@ -3552,7 +3577,7 @@ pub unsafe trait FromBytes: FromZeros {
3552
3577
{
3553
3578
static_assert_dst_is_not_zst ! ( Self ) ;
3554
3579
match Ptr :: from_ref ( source) . try_cast_into_no_leftover :: < _ , BecauseImmutable > ( None ) {
3555
- Ok ( ptr) => Ok ( ptr. bikeshed_recall_valid ( ) . as_ref ( ) ) ,
3580
+ Ok ( ptr) => Ok ( ptr. recall_validity ( ) . as_ref ( ) ) ,
3556
3581
Err ( err) => Err ( err. map_src ( |src| src. as_ref ( ) ) ) ,
3557
3582
}
3558
3583
}
@@ -3788,7 +3813,7 @@ pub unsafe trait FromBytes: FromZeros {
3788
3813
{
3789
3814
static_assert_dst_is_not_zst ! ( Self ) ;
3790
3815
match Ptr :: from_mut ( source) . try_cast_into_no_leftover :: < _ , BecauseExclusive > ( None ) {
3791
- Ok ( ptr) => Ok ( ptr. bikeshed_recall_valid ( ) . as_mut ( ) ) ,
3816
+ Ok ( ptr) => Ok ( ptr. recall_validity ( ) . as_mut ( ) ) ,
3792
3817
Err ( err) => Err ( err. map_src ( |src| src. as_mut ( ) ) ) ,
3793
3818
}
3794
3819
}
@@ -4027,7 +4052,7 @@ pub unsafe trait FromBytes: FromZeros {
4027
4052
let source = Ptr :: from_ref ( source) ;
4028
4053
let maybe_slf = source. try_cast_into_no_leftover :: < _ , BecauseImmutable > ( Some ( count) ) ;
4029
4054
match maybe_slf {
4030
- Ok ( slf) => Ok ( slf. bikeshed_recall_valid ( ) . as_ref ( ) ) ,
4055
+ Ok ( slf) => Ok ( slf. recall_validity ( ) . as_ref ( ) ) ,
4031
4056
Err ( err) => Err ( err. map_src ( |s| s. as_ref ( ) ) ) ,
4032
4057
}
4033
4058
}
@@ -4258,7 +4283,9 @@ pub unsafe trait FromBytes: FromZeros {
4258
4283
let source = Ptr :: from_mut ( source) ;
4259
4284
let maybe_slf = source. try_cast_into_no_leftover :: < _ , BecauseImmutable > ( Some ( count) ) ;
4260
4285
match maybe_slf {
4261
- Ok ( slf) => Ok ( slf. bikeshed_recall_valid ( ) . as_mut ( ) ) ,
4286
+ Ok ( slf) => Ok ( slf
4287
+ . recall_validity :: < _ , ( _ , ( _ , ( BecauseExclusive , BecauseExclusive ) ) ) > ( )
4288
+ . as_mut ( ) ) ,
4262
4289
Err ( err) => Err ( err. map_src ( |s| s. as_mut ( ) ) ) ,
4263
4290
}
4264
4291
}
@@ -4716,7 +4743,7 @@ fn ref_from_prefix_suffix<T: FromBytes + KnownLayout + Immutable + ?Sized>(
4716
4743
let ( slf, prefix_suffix) = Ptr :: from_ref ( source)
4717
4744
. try_cast_into :: < _ , BecauseImmutable > ( cast_type, meta)
4718
4745
. map_err ( |err| err. map_src ( |s| s. as_ref ( ) ) ) ?;
4719
- Ok ( ( slf. bikeshed_recall_valid ( ) . as_ref ( ) , prefix_suffix. as_ref ( ) ) )
4746
+ Ok ( ( slf. recall_validity ( ) . as_ref ( ) , prefix_suffix. as_ref ( ) ) )
4720
4747
}
4721
4748
4722
4749
/// Interprets the given affix of the given bytes as a `&mut Self` without
@@ -4728,15 +4755,15 @@ fn ref_from_prefix_suffix<T: FromBytes + KnownLayout + Immutable + ?Sized>(
4728
4755
/// If there are insufficient bytes, or if that affix of `source` is not
4729
4756
/// appropriately aligned, this returns `Err`.
4730
4757
#[ inline( always) ]
4731
- fn mut_from_prefix_suffix < T : FromBytes + KnownLayout + ?Sized > (
4758
+ fn mut_from_prefix_suffix < T : FromBytes + IntoBytes + KnownLayout + ?Sized > (
4732
4759
source : & mut [ u8 ] ,
4733
4760
meta : Option < T :: PointerMetadata > ,
4734
4761
cast_type : CastType ,
4735
4762
) -> Result < ( & mut T , & mut [ u8 ] ) , CastError < & mut [ u8 ] , T > > {
4736
4763
let ( slf, prefix_suffix) = Ptr :: from_mut ( source)
4737
4764
. try_cast_into :: < _ , BecauseExclusive > ( cast_type, meta)
4738
4765
. map_err ( |err| err. map_src ( |s| s. as_mut ( ) ) ) ?;
4739
- Ok ( ( slf. bikeshed_recall_valid ( ) . as_mut ( ) , prefix_suffix. as_mut ( ) ) )
4766
+ Ok ( ( slf. recall_validity ( ) . as_mut ( ) , prefix_suffix. as_mut ( ) ) )
4740
4767
}
4741
4768
4742
4769
/// Analyzes whether a type is [`IntoBytes`].
0 commit comments