@@ -12,8 +12,8 @@ use core::{
1212 ptr:: NonNull ,
1313} ;
1414
15- use super :: { inner:: PtrInner , invariant:: * } ;
1615use crate :: {
16+ pointer:: { inner:: PtrInner , invariant:: * , transmute:: TransmuteFromPtr } ,
1717 util:: { AlignmentVariance , Covariant , TransparentWrapper , ValidityVariance } ,
1818 AlignmentError , CastError , CastType , KnownLayout , SizeError , TryFromBytes , ValidityError ,
1919} ;
@@ -391,7 +391,7 @@ mod _conversions {
391391 {
392392 /// Converts `self` to a transparent wrapper type into a `Ptr` to the
393393 /// wrapped inner type.
394- pub ( crate ) fn transparent_wrapper_into_inner (
394+ fn transparent_wrapper_into_inner (
395395 self ,
396396 ) -> Ptr <
397397 ' a ,
@@ -430,6 +430,17 @@ mod _conversions {
430430 where
431431 I : Invariants ,
432432 {
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+
433444 /// Casts to a different (unsized) target type without checking interior
434445 /// mutability.
435446 ///
@@ -460,14 +471,14 @@ mod _conversions {
460471 ) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , V ) >
461472 where
462473 V : Validity ,
463- F : FnOnce ( * mut T ) -> * mut U ,
474+ F : FnOnce ( NonNull < T > ) -> NonNull < U > ,
464475 {
465- let ptr = cast ( self . as_inner ( ) . as_non_null ( ) . as_ptr ( ) ) ;
476+ let ptr = cast ( self . as_inner ( ) . as_non_null ( ) ) ;
466477
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) };
471482
472483 // SAFETY:
473484 //
@@ -552,7 +563,7 @@ mod _conversions {
552563 // validity of the other.
553564 let ptr = unsafe {
554565 #[ 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 > > )
556567 } ;
557568 ptr. bikeshed_recall_aligned ( )
558569 }
@@ -561,6 +572,8 @@ mod _conversions {
561572
562573/// State transitions between invariants.
563574mod _transitions {
575+ use crate :: pointer:: transmute:: TryTransmuteFromPtr ;
576+
564577 use super :: * ;
565578
566579 impl < ' a , T , I > Ptr < ' a , T , I >
@@ -819,14 +832,11 @@ mod _transitions {
819832 #[ inline]
820833 // TODO(#859): Reconsider the name of this method before making it
821834 // 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 ) >
823836 where
824- T : crate :: FromBytes ,
837+ T : crate :: FromBytes + TryTransmuteFromPtr < T , I :: Aliasing , I :: Validity , Valid , R > ,
825838 I : Invariants < Validity = Initialized > ,
826839 {
827- // TODO(#1866): Fix this unsoundness.
828-
829- // SAFETY: This is unsound!
830840 unsafe { self . assume_valid ( ) }
831841 }
832842
@@ -843,24 +853,24 @@ mod _transitions {
843853 /// On error, unsafe code may rely on this method's returned
844854 /// `ValidityError` containing `self`.
845855 #[ inline]
846- pub ( crate ) fn try_into_valid < R > (
856+ pub ( crate ) fn try_into_valid < R , S > (
847857 mut self ,
848858 ) -> Result < Ptr < ' a , T , ( I :: Aliasing , I :: Alignment , Valid ) > , ValidityError < Self , T > >
849859 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 > ,
851863 I :: Aliasing : Reference ,
852864 I : Invariants < Validity = Initialized > ,
853865 {
854866 // This call may panic. If that happens, it doesn't cause any soundness
855867 // issues, as we have not generated any invalid state which we need to
856868 // fix before returning.
857869 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.
860871 //
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`.
864874 Ok ( unsafe { self . assume_valid ( ) } )
865875 } else {
866876 Err ( ValidityError :: new ( self ) )
@@ -904,7 +914,7 @@ mod _casts {
904914 /// at ranges identical to those at which `UnsafeCell`s exist in `*p`
905915 #[ doc( hidden) ]
906916 #[ 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 > > (
908918 self ,
909919 cast : F ,
910920 ) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , I :: Validity ) >
@@ -947,7 +957,7 @@ mod _casts {
947957 where
948958 T : Read < I :: Aliasing , R > ,
949959 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 > ,
951961 {
952962 // SAFETY: Because `T` and `U` both implement `Read<I::Aliasing, _>`,
953963 // either:
@@ -988,9 +998,8 @@ mod _casts {
988998 // returned pointer addresses the same bytes as `p`
989999 // - `slice_from_raw_parts_mut` and `.cast` both preserve provenance
9901000 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)
9941003 } )
9951004 } ;
9961005
@@ -1214,7 +1223,7 @@ mod _casts {
12141223 // inner type `T`. A consequence of this guarantee is that it is
12151224 // possible to convert between `T` and `UnsafeCell<T>`.
12161225 #[ 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 > ) ) } ;
12181227
12191228 // SAFETY: `UnsafeCell<T>` has the same alignment as `T` [1],
12201229 // and so if `self` is guaranteed to be aligned, then so is the
@@ -1321,10 +1330,12 @@ mod tests {
13211330 } ;
13221331
13231332 // 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+ > (
13251336 slf : Ptr < ' _ , T , ( Shared , Aligned , Initialized ) > ,
13261337 ) -> usize {
1327- let t = slf. bikeshed_recall_valid ( ) . as_ref ( ) ;
1338+ let t = slf. bikeshed_recall_valid :: < BecauseImmutable > ( ) . as_ref ( ) ;
13281339
13291340 let bytes = {
13301341 let len = mem:: size_of_val ( t) ;
0 commit comments