@@ -995,6 +995,18 @@ mod _casts {
995995 }
996996 }
997997
998+ impl < Src , NewSrc , Dst > Map < NewSrc > for crate :: CastError < Src , Dst >
999+ where
1000+ Dst : ?Sized ,
1001+ {
1002+ type Input = Src ;
1003+ type Output = crate :: CastError < NewSrc , Dst > ;
1004+
1005+ fn map < F : FnOnce ( Src ) -> NewSrc > ( self , f : F ) -> Self :: Output {
1006+ self . map_src ( f)
1007+ }
1008+ }
1009+
9981010 impl < ' a , T , I > Ptr < ' a , T , I >
9991011 where
10001012 T : ' a + KnownLayout + ?Sized ,
@@ -1159,30 +1171,18 @@ mod _casts {
11591171 U : ' a + ?Sized + KnownLayout + Read < I :: Aliasing , R > ,
11601172 [ u8 ] : Read < I :: Aliasing , R > ,
11611173 {
1162- // FIXME(#67): Remove this allow. See NonNullExt for more details.
1163- #[ allow( unstable_name_collisions) ]
1164- match self . try_cast_into ( CastType :: Prefix , meta) {
1165- Ok ( ( slf, remainder) ) => {
1166- if remainder. len ( ) == 0 {
1167- Ok ( slf)
1168- } else {
1169- // Undo the cast so we can return the original bytes.
1170- let slf = slf. as_bytes ( ) ;
1171- // Restore the initial alignment invariant of `self`.
1172- //
1173- // SAFETY: The referent type of `slf` is now equal to
1174- // that of `self`, but the alignment invariants
1175- // nominally differ. Since `slf` and `self` refer to the
1176- // same memory and no actions have been taken that would
1177- // violate the original invariants on `self`, it is
1178- // sound to apply the alignment invariant of `self` onto
1179- // `slf`.
1180- let slf = unsafe { slf. assume_alignment :: < I :: Alignment > ( ) } ;
1181- let slf = slf. unify_invariants ( ) ;
1182- Err ( CastError :: Size ( SizeError :: < _ , U > :: new ( slf) ) )
1174+ // SAFETY: The provided closure returns the only copy of `slf`.
1175+ unsafe {
1176+ self . try_with_unchecked ( |slf| match slf. try_cast_into ( CastType :: Prefix , meta) {
1177+ Ok ( ( slf, remainder) ) => {
1178+ if remainder. len ( ) == 0 {
1179+ Ok ( slf)
1180+ } else {
1181+ Err ( CastError :: Size ( SizeError :: < _ , U > :: new ( ( ) ) ) )
1182+ }
11831183 }
1184- }
1185- Err ( err ) => Err ( err ) ,
1184+ Err ( err ) => Err ( err . map_src ( |_slf| ( ) ) ) ,
1185+ } )
11861186 }
11871187 }
11881188 }
@@ -1520,4 +1520,18 @@ mod tests {
15201520 // succeed.
15211521 test ! ( Dst , 8 , usize :: MAX - 8 + 1 , None ) ;
15221522 }
1523+
1524+ #[ test]
1525+ fn test_try_cast_into_no_leftover_restores_original_slice ( ) {
1526+ let bytes = [ 0u8 ; 4 ] ;
1527+ let ptr = Ptr :: from_ref ( & bytes[ ..] ) ;
1528+ let res = ptr. try_cast_into_no_leftover :: < u16 , BecauseImmutable > ( None ) ;
1529+ match res {
1530+ Ok ( _) => panic ! ( "should have failed due to leftover bytes" ) ,
1531+ Err ( CastError :: Size ( e) ) => {
1532+ assert_eq ! ( e. into_src( ) . len( ) , 4 , "Should return original slice length" ) ;
1533+ }
1534+ Err ( e) => panic ! ( "wrong error type: {:?}" , e) ,
1535+ }
1536+ }
15231537}
0 commit comments