@@ -12,8 +12,8 @@ use core::{
12
12
ptr:: NonNull ,
13
13
} ;
14
14
15
- use super :: { inner:: PtrInner , invariant:: * } ;
16
15
use crate :: {
16
+ pointer:: { inner:: PtrInner , invariant:: * , transmute:: TransmuteFromPtr } ,
17
17
util:: { AlignmentVariance , Covariant , TransparentWrapper , ValidityVariance } ,
18
18
AlignmentError , CastError , CastType , KnownLayout , SizeError , TryFromBytes , ValidityError ,
19
19
} ;
@@ -391,7 +391,7 @@ mod _conversions {
391
391
{
392
392
/// Converts `self` to a transparent wrapper type into a `Ptr` to the
393
393
/// wrapped inner type.
394
- pub ( crate ) fn transparent_wrapper_into_inner (
394
+ fn transparent_wrapper_into_inner (
395
395
self ,
396
396
) -> Ptr <
397
397
' a ,
@@ -430,6 +430,17 @@ mod _conversions {
430
430
where
431
431
I : Invariants ,
432
432
{
433
+ pub fn transmute < U , V , R > ( self ) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , V ) >
434
+ where
435
+ T : KnownLayout ,
436
+ V : Validity ,
437
+ U : TransmuteFromPtr < T , I :: Aliasing , I :: Validity , V , R >
438
+ + KnownLayout < PointerMetadata = T :: PointerMetadata >
439
+ + ?Sized ,
440
+ {
441
+ self . transmute_unchecked ( |t : NonNull < T > | U :: cast_from_raw ( t) )
442
+ }
443
+
433
444
/// Casts to a different (unsized) target type without checking interior
434
445
/// mutability.
435
446
///
@@ -460,14 +471,14 @@ mod _conversions {
460
471
) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , V ) >
461
472
where
462
473
V : Validity ,
463
- F : FnOnce ( * mut T ) -> * mut U ,
474
+ F : FnOnce ( NonNull < T > ) -> NonNull < U > ,
464
475
{
465
- let ptr = cast ( self . as_inner ( ) . as_non_null ( ) . as_ptr ( ) ) ;
476
+ let ptr = cast ( self . as_inner ( ) . as_non_null ( ) ) ;
466
477
467
- // SAFETY: Caller promises that `cast` returns a pointer whose
468
- // address is in the range of `self.as_inner().as_non_null()`'s referent. By
469
- // invariant, none of these addresses are null.
470
- let ptr = unsafe { NonNull :: new_unchecked ( ptr) } ;
478
+ // // SAFETY: Caller promises that `cast` returns a pointer whose
479
+ // // address is in the range of `self.as_inner().as_non_null()`'s referent. By
480
+ // // invariant, none of these addresses are null.
481
+ // let ptr = unsafe { NonNull::new_unchecked(ptr) };
471
482
472
483
// SAFETY:
473
484
//
@@ -552,7 +563,7 @@ mod _conversions {
552
563
// validity of the other.
553
564
let ptr = unsafe {
554
565
#[ allow( clippy:: as_conversions) ]
555
- self . transmute_unchecked ( | p : * mut T | p as * mut crate :: Unalign < T > )
566
+ self . transmute_unchecked ( NonNull :: cast :: < crate :: Unalign < T > > )
556
567
} ;
557
568
ptr. bikeshed_recall_aligned ( )
558
569
}
@@ -561,6 +572,8 @@ mod _conversions {
561
572
562
573
/// State transitions between invariants.
563
574
mod _transitions {
575
+ use crate :: pointer:: transmute:: TryTransmuteFromPtr ;
576
+
564
577
use super :: * ;
565
578
566
579
impl < ' a , T , I > Ptr < ' a , T , I >
@@ -819,14 +832,11 @@ mod _transitions {
819
832
#[ inline]
820
833
// TODO(#859): Reconsider the name of this method before making it
821
834
// public.
822
- pub fn bikeshed_recall_valid ( self ) -> Ptr < ' a , T , ( I :: Aliasing , I :: Alignment , Valid ) >
835
+ pub fn bikeshed_recall_valid < R > ( self ) -> Ptr < ' a , T , ( I :: Aliasing , I :: Alignment , Valid ) >
823
836
where
824
- T : crate :: FromBytes ,
837
+ T : crate :: FromBytes + TryTransmuteFromPtr < T , I :: Aliasing , I :: Validity , Valid , R > ,
825
838
I : Invariants < Validity = Initialized > ,
826
839
{
827
- // TODO(#1866): Fix this unsoundness.
828
-
829
- // SAFETY: This is unsound!
830
840
unsafe { self . assume_valid ( ) }
831
841
}
832
842
@@ -843,24 +853,24 @@ mod _transitions {
843
853
/// On error, unsafe code may rely on this method's returned
844
854
/// `ValidityError` containing `self`.
845
855
#[ inline]
846
- pub ( crate ) fn try_into_valid < R > (
856
+ pub ( crate ) fn try_into_valid < R , S > (
847
857
mut self ,
848
858
) -> Result < Ptr < ' a , T , ( I :: Aliasing , I :: Alignment , Valid ) > , ValidityError < Self , T > >
849
859
where
850
- T : TryFromBytes + Read < I :: Aliasing , R > ,
860
+ T : TryFromBytes
861
+ + Read < I :: Aliasing , R >
862
+ + TryTransmuteFromPtr < T , I :: Aliasing , I :: Validity , Valid , S > ,
851
863
I :: Aliasing : Reference ,
852
864
I : Invariants < Validity = Initialized > ,
853
865
{
854
866
// This call may panic. If that happens, it doesn't cause any soundness
855
867
// issues, as we have not generated any invalid state which we need to
856
868
// fix before returning.
857
869
if T :: is_bit_valid ( self . reborrow ( ) . forget_aligned ( ) ) {
858
- // SAFETY: If `T::is_bit_valid`, code may assume that `self`
859
- // contains a bit-valid instance of `Self`.
870
+ // TODO: Complete this safety comment.
860
871
//
861
- // TODO(#1866): This is unsound! The returned `Ptr` may permit
862
- // writing referents which do not satisfy the `Initialized`
863
- // validity invariant of `self`.
872
+ // If `T::is_bit_valid`, code may assume that `self` contains a
873
+ // bit-valid instance of `Self`.
864
874
Ok ( unsafe { self . assume_valid ( ) } )
865
875
} else {
866
876
Err ( ValidityError :: new ( self ) )
@@ -904,7 +914,7 @@ mod _casts {
904
914
/// at ranges identical to those at which `UnsafeCell`s exist in `*p`
905
915
#[ doc( hidden) ]
906
916
#[ inline]
907
- pub unsafe fn cast_unsized_unchecked < U , F : FnOnce ( * mut T ) -> * mut U > (
917
+ pub unsafe fn cast_unsized_unchecked < U , F : FnOnce ( NonNull < T > ) -> NonNull < U > > (
908
918
self ,
909
919
cast : F ,
910
920
) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , I :: Validity ) >
@@ -947,7 +957,7 @@ mod _casts {
947
957
where
948
958
T : Read < I :: Aliasing , R > ,
949
959
U : ' a + ?Sized + Read < I :: Aliasing , S > + CastableFrom < T , I :: Validity , I :: Validity > ,
950
- F : FnOnce ( * mut T ) -> * mut U ,
960
+ F : FnOnce ( NonNull < T > ) -> NonNull < U > ,
951
961
{
952
962
// SAFETY: Because `T` and `U` both implement `Read<I::Aliasing, _>`,
953
963
// either:
@@ -988,9 +998,8 @@ mod _casts {
988
998
// returned pointer addresses the same bytes as `p`
989
999
// - `slice_from_raw_parts_mut` and `.cast` both preserve provenance
990
1000
let ptr: Ptr < ' a , [ u8 ] , _ > = unsafe {
991
- self . cast_unsized ( |p : * mut T | {
992
- #[ allow( clippy:: as_conversions) ]
993
- core:: ptr:: slice_from_raw_parts_mut ( p. cast :: < u8 > ( ) , bytes)
1001
+ self . cast_unsized ( |p : NonNull < T > | {
1002
+ core:: ptr:: NonNull :: slice_from_raw_parts ( p. cast :: < u8 > ( ) , bytes)
994
1003
} )
995
1004
} ;
996
1005
@@ -1214,7 +1223,7 @@ mod _casts {
1214
1223
// inner type `T`. A consequence of this guarantee is that it is
1215
1224
// possible to convert between `T` and `UnsafeCell<T>`.
1216
1225
#[ allow( clippy:: as_conversions) ]
1217
- let ptr = unsafe { self . transmute_unchecked ( |p| p as * mut T ) } ;
1226
+ let ptr = unsafe { self . transmute_unchecked ( |p| cast ! ( p => NonNull < T > ) ) } ;
1218
1227
1219
1228
// SAFETY: `UnsafeCell<T>` has the same alignment as `T` [1],
1220
1229
// and so if `self` is guaranteed to be aligned, then so is the
@@ -1321,10 +1330,12 @@ mod tests {
1321
1330
} ;
1322
1331
1323
1332
// SAFETY: The bytes in `slf` must be initialized.
1324
- unsafe fn validate_and_get_len < T : ?Sized + KnownLayout + FromBytes > (
1333
+ unsafe fn validate_and_get_len <
1334
+ T : ?Sized + KnownLayout + FromBytes + Immutable ,
1335
+ > (
1325
1336
slf : Ptr < ' _ , T , ( Shared , Aligned , Initialized ) > ,
1326
1337
) -> usize {
1327
- let t = slf. bikeshed_recall_valid ( ) . as_ref ( ) ;
1338
+ let t = slf. bikeshed_recall_valid :: < BecauseImmutable > ( ) . as_ref ( ) ;
1328
1339
1329
1340
let bytes = {
1330
1341
let len = mem:: size_of_val ( t) ;
0 commit comments