@@ -12,9 +12,12 @@ use core::{
1212    ptr:: NonNull , 
1313} ; 
1414
15- use  super :: { inner:: PtrInner ,  invariant:: * } ; 
1615use  crate :: { 
17-     util:: { AlignmentVariance ,  Covariant ,  TransparentWrapper ,  ValidityVariance } , 
16+     pointer:: { 
17+         inner:: PtrInner , 
18+         invariant:: * , 
19+         transmute:: { Foo ,  TransmuteFromPtr } , 
20+     } , 
1821    AlignmentError ,  CastError ,  CastType ,  KnownLayout ,  SizeError ,  TryFromBytes ,  ValidityError , 
1922} ; 
2023
@@ -383,53 +386,31 @@ mod _conversions {
383386        } 
384387    } 
385388
386-     /// `Ptr<'a, T = Wrapper<U>>` → `Ptr<'a, U>` 
387-      impl < ' a ,  T ,  I >  Ptr < ' a ,  T ,  I > 
388-     where 
389-         T :  ' a  + TransparentWrapper < I ,  UnsafeCellVariance  = Covariant >  + ?Sized , 
390-         I :  Invariants , 
391-     { 
392-         /// Converts `self` to a transparent wrapper type into a `Ptr` to the 
393-          /// wrapped inner type. 
394-          pub ( crate )  fn  transparent_wrapper_into_inner ( 
395-             self , 
396-         )  -> Ptr < 
397-             ' a , 
398-             T :: Inner , 
399-             ( 
400-                 I :: Aliasing , 
401-                 <T :: AlignmentVariance  as  AlignmentVariance < I :: Alignment > >:: Applied , 
402-                 <T :: ValidityVariance  as  ValidityVariance < I :: Validity > >:: Applied , 
403-             ) , 
404-         >  { 
405-             // SAFETY: 
406-             // - By invariant on `TransparentWrapper::cast_into_inner`: 
407-             //   - This cast preserves address and referent size, and thus the 
408-             //     returned pointer addresses the same bytes as `p` 
409-             //   - This cast preserves provenance 
410-             // - By invariant on `TransparentWrapper<UnsafeCellVariance = 
411-             //   Covariant>`, `T` and `T::Inner` have `UnsafeCell`s at the same 
412-             //   byte ranges. Since `p` and the returned pointer address the 
413-             //   same byte range, they refer to `UnsafeCell`s at the same byte 
414-             //   ranges. 
415-             // - By invariant on `TransparentWrapper`, since `self` satisfies 
416-             //   the validity invariant `I::Validity`, the returned pointer (of 
417-             //   type `T::Inner`) satisfies the given "applied" validity 
418-             //   invariant. 
419-             let  ptr = unsafe  {  self . transmute_unchecked ( |p| T :: cast_into_inner ( p) )  } ; 
420-             // SAFETY: By invariant on `TransparentWrapper`, since `self` 
421-             // satisfies the alignment invariant `I::Alignment`, the returned 
422-             // pointer (of type `T::Inner`) satisfies the given "applied" 
423-             // alignment invariant. 
424-             unsafe  {  ptr. assume_alignment ( )  } 
425-         } 
426-     } 
427- 
428389    /// `Ptr<'a, T>` → `Ptr<'a, U>` 
429390     impl < ' a ,  T :  ?Sized ,  I >  Ptr < ' a ,  T ,  I > 
430391    where 
431392        I :  Invariants , 
432393    { 
394+         pub ( crate )  fn  transmute < U ,  V ,  R > ( self )  -> Ptr < ' a ,  U ,  ( I :: Aliasing ,  Unaligned ,  V ) > 
395+         where 
396+             T :  KnownLayout , 
397+             V :  Validity , 
398+             U :  TransmuteFromPtr < T ,  I :: Aliasing ,  I :: Validity ,  V ,  R > 
399+                 + KnownLayout < PointerMetadata  = T :: PointerMetadata > 
400+                 + ?Sized , 
401+         { 
402+             unsafe  {  self . transmute_unchecked ( |t :  NonNull < T > | U :: cast_from_raw ( t) )  } 
403+         } 
404+ 
405+         pub ( crate )  fn  transmute_sized < U ,  V ,  R > ( self )  -> Ptr < ' a ,  U ,  ( I :: Aliasing ,  Unaligned ,  V ) > 
406+         where 
407+             T :  Sized , 
408+             V :  Validity , 
409+             U :  TransmuteFromPtr < T ,  I :: Aliasing ,  I :: Validity ,  V ,  R > , 
410+         { 
411+             unsafe  {  self . transmute_unchecked ( |t :  NonNull < T > | cast ! ( t => NonNull <U >) )  } 
412+         } 
413+ 
433414        /// Casts to a different (unsized) target type without checking interior 
434415         /// mutability. 
435416         /// 
@@ -460,14 +441,9 @@ mod _conversions {
460441        )  -> Ptr < ' a ,  U ,  ( I :: Aliasing ,  Unaligned ,  V ) > 
461442        where 
462443            V :  Validity , 
463-             F :  FnOnce ( * mut   T )  -> * mut   U , 
444+             F :  FnOnce ( NonNull < T > )  -> NonNull < U > , 
464445        { 
465-             let  ptr = cast ( self . as_inner ( ) . as_non_null ( ) . as_ptr ( ) ) ; 
466- 
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)  } ; 
446+             let  ptr = cast ( self . as_inner ( ) . as_non_null ( ) ) ; 
471447
472448            // SAFETY: 
473449            // 
@@ -552,7 +528,7 @@ mod _conversions {
552528            //   validity of the other. 
553529            let  ptr = unsafe  { 
554530                #[ allow( clippy:: as_conversions) ]  
555-                 self . transmute_unchecked ( | p :   * mut   T | p  as   * mut   crate :: Unalign < T > ) 
531+                 self . transmute_unchecked ( NonNull :: cast :: < crate :: Unalign < T > > ) 
556532            } ; 
557533            ptr. bikeshed_recall_aligned ( ) 
558534        } 
@@ -561,6 +537,8 @@ mod _conversions {
561537
562538/// State transitions between invariants. 
563539mod  _transitions { 
540+     use  crate :: pointer:: transmute:: TryTransmuteFromPtr ; 
541+ 
564542    use  super :: * ; 
565543
566544    impl < ' a ,  T ,  I >  Ptr < ' a ,  T ,  I > 
@@ -819,14 +797,11 @@ mod _transitions {
819797        #[ inline]  
820798        // TODO(#859): Reconsider the name of this method before making it 
821799        // public. 
822-         pub  fn  bikeshed_recall_valid ( self )  -> Ptr < ' a ,  T ,  ( I :: Aliasing ,  I :: Alignment ,  Valid ) > 
800+         pub  fn  bikeshed_recall_valid < R > ( self )  -> Ptr < ' a ,  T ,  ( I :: Aliasing ,  I :: Alignment ,  Valid ) > 
823801        where 
824-             T :  crate :: FromBytes , 
802+             T :  crate :: FromBytes  +  TryTransmuteFromPtr < T ,   I :: Aliasing ,   I :: Validity ,   Valid ,   R > , 
825803            I :  Invariants < Validity  = Initialized > , 
826804        { 
827-             // TODO(#1866): Fix this unsoundness. 
828- 
829-             // SAFETY: This is unsound! 
830805            unsafe  {  self . assume_valid ( )  } 
831806        } 
832807
@@ -843,24 +818,24 @@ mod _transitions {
843818         /// On error, unsafe code may rely on this method's returned 
844819         /// `ValidityError` containing `self`. 
845820         #[ inline]  
846-         pub ( crate )  fn  try_into_valid < R > ( 
821+         pub ( crate )  fn  try_into_valid < R ,   S > ( 
847822            mut  self , 
848823        )  -> Result < Ptr < ' a ,  T ,  ( I :: Aliasing ,  I :: Alignment ,  Valid ) > ,  ValidityError < Self ,  T > > 
849824        where 
850-             T :  TryFromBytes  + Read < I :: Aliasing ,  R > , 
825+             T :  TryFromBytes 
826+                 + Read < I :: Aliasing ,  R > 
827+                 + TryTransmuteFromPtr < T ,  I :: Aliasing ,  I :: Validity ,  Valid ,  S > , 
851828            I :: Aliasing :  Reference , 
852829            I :  Invariants < Validity  = Initialized > , 
853830        { 
854831            // This call may panic. If that happens, it doesn't cause any soundness 
855832            // issues, as we have not generated any invalid state which we need to 
856833            // fix before returning. 
857834            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`. 
835+                 // TODO: Complete this safety comment. 
860836                // 
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`. 
837+                 // If `T::is_bit_valid`, code may assume that `self` contains a 
838+                 // bit-valid instance of `Self`. 
864839                Ok ( unsafe  {  self . assume_valid ( )  } ) 
865840            }  else  { 
866841                Err ( ValidityError :: new ( self ) ) 
@@ -902,9 +877,10 @@ mod _casts {
902877         /// - `u` has the same provenance as `p` 
903878         /// - If `I::Aliasing` is [`Shared`], `UnsafeCell`s in `*u` must exist 
904879         ///   at ranges identical to those at which `UnsafeCell`s exist in `*p` 
880+          /// TODO: UnsafeCell compatibility 
905881         #[ doc( hidden) ]  
906882        #[ inline]  
907-         pub  unsafe  fn  cast_unsized_unchecked < U ,  F :  FnOnce ( * mut   T )  -> * mut   U > ( 
883+         pub ( crate )  unsafe  fn  cast_unsized_unchecked < U ,  F :  FnOnce ( NonNull < T > )  -> NonNull < U > > ( 
908884            self , 
909885            cast :  F , 
910886        )  -> Ptr < ' a ,  U ,  ( I :: Aliasing ,  Unaligned ,  I :: Validity ) > 
@@ -940,20 +916,29 @@ mod _casts {
940916         /// - `u` has the same provenance as `p` 
941917         #[ doc( hidden) ]  
942918        #[ inline]  
943-         pub  unsafe  fn  cast_unsized < U ,  F ,  R ,   S > ( 
919+         pub  unsafe  fn  cast_unsized < U ,  F ,  R > ( 
944920            self , 
945921            cast :  F , 
946922        )  -> Ptr < ' a ,  U ,  ( I :: Aliasing ,  Unaligned ,  I :: Validity ) > 
947923        where 
948-             T :  Read < I :: Aliasing ,  R > , 
949-             U :  ' a  + ?Sized  + Read < I :: Aliasing ,   S >  +  CastableFrom < T ,  I :: Validity ,  I :: Validity > , 
950-             F :  FnOnce ( * mut   T )  -> * mut   U , 
924+             T :  Foo < U ,   I :: Aliasing ,  R > , 
925+             U :  ' a  + ?Sized  + CastableFrom < T ,  I :: Validity ,  I :: Validity > , 
926+             F :  FnOnce ( NonNull < T > )  -> NonNull < U > , 
951927        { 
952-             // SAFETY: Because `T` and `U` both implement `Read<I::Aliasing, _>`, 
953-             // either: 
954-             // - `I::Aliasing` is `Exclusive` 
955-             // - `T` and `U` are both `Immutable`, in which case they trivially 
956-             //   contain `UnsafeCell`s at identical locations 
928+             // SAFETY: Because `T: Foo<U, I::Aliasing, R>`, one of the following 
929+             // holds: 
930+             // - `T: Read<I::Aliasing>` and `U: Read<I::Aliasing>`, in which 
931+             //   case one of the following holds: 
932+             //   - `I::Aliasing` is `Exclusive` 
933+             //   - `T` and `U` are both `Immutable` 
934+             // - `T` and `U` contain `UnsafeCell`s at identical locations 
935+             // 
936+             // In the first case, `I::Aliasing` is `Exclusive`, and in the 
937+             // second and third case, `T` and `U` contain `UnsafeCell`s at 
938+             // identical locations (in the second case, this is because `T` and 
939+             // `U` contain no `UnsafeCell`s at all). 
940+             // 
941+             // TODO: This should also promise UnsafeCell compatibility 
957942            // 
958943            // The caller promises all other safety preconditions. 
959944            unsafe  {  self . cast_unsized_unchecked ( cast)  } 
@@ -988,9 +973,8 @@ mod _casts {
988973            //   returned pointer addresses the same bytes as `p` 
989974            // - `slice_from_raw_parts_mut` and `.cast` both preserve provenance 
990975            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) 
976+                 self . cast_unsized ( |p :  NonNull < T > | { 
977+                     core:: ptr:: NonNull :: slice_from_raw_parts ( p. cast :: < u8 > ( ) ,  bytes) 
994978                } ) 
995979            } ; 
996980
@@ -1214,7 +1198,7 @@ mod _casts {
12141198            //   inner type `T`. A consequence of this guarantee is that it is 
12151199            //   possible to convert between `T` and `UnsafeCell<T>`. 
12161200            #[ allow( clippy:: as_conversions) ]  
1217-             let  ptr = unsafe  {  self . transmute_unchecked ( |p| p  as   * mut   T )  } ; 
1201+             let  ptr = unsafe  {  self . transmute_unchecked ( |p| cast ! ( p =>  NonNull < T > ) )  } ; 
12181202
12191203            // SAFETY: `UnsafeCell<T>` has the same alignment as `T` [1], 
12201204            // and so if `self` is guaranteed to be aligned, then so is the 
@@ -1321,10 +1305,12 @@ mod tests {
13211305                    } ; 
13221306
13231307                    // SAFETY: The bytes in `slf` must be initialized. 
1324-                     unsafe  fn  validate_and_get_len < T :  ?Sized  + KnownLayout  + FromBytes > ( 
1308+                     unsafe  fn  validate_and_get_len < 
1309+                         T :  ?Sized  + KnownLayout  + FromBytes  + Immutable , 
1310+                     > ( 
13251311                        slf :  Ptr < ' _ ,  T ,  ( Shared ,  Aligned ,  Initialized ) > , 
13261312                    )  -> usize  { 
1327-                         let  t = slf. bikeshed_recall_valid ( ) . as_ref ( ) ; 
1313+                         let  t = slf. bikeshed_recall_valid :: < BecauseImmutable > ( ) . as_ref ( ) ; 
13281314
13291315                        let  bytes = { 
13301316                            let  len = mem:: size_of_val ( t) ; 
0 commit comments