@@ -427,7 +427,7 @@ impl<T: ?Sized> *mut T {
427
427
// Precondition 2: adding the computed offset to `self` does not cause overflow.
428
428
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
429
429
count. checked_mul( core:: mem:: size_of:: <T >( ) as isize )
430
- . map_or ( false , |computed_offset| ( self as isize ) . checked_add( computed_offset) . is_some( ) ) &&
430
+ . is_some_and ( |computed_offset| ( self as isize ) . checked_add( computed_offset) . is_some( ) ) &&
431
431
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
432
432
// Otherwise, for non-unit types, `self` and `self.wrapping_offset(count)` should point to the same allocated object,
433
433
// restricting `count` to prevent crossing allocation boundaries.
@@ -493,19 +493,14 @@ impl<T: ?Sized> *mut T {
493
493
#[ rustc_const_stable( feature = "const_pointer_byte_offsets" , since = "1.75.0" ) ]
494
494
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
495
495
#[ requires(
496
- // If count is zero, any pointer is valid including null pointer.
497
- ( count == 0 ) ||
498
- // Else if count is not zero, then ensure that subtracting `count` doesn't
499
- // cause overflow and that both pointers `self` and the result are in the
500
- // same allocation.
501
- ( ( self . addr( ) as isize ) . checked_add( count) . is_some( ) &&
502
- core:: ub_checks:: same_allocation( self , self . wrapping_byte_offset( count) ) )
503
- ) ]
504
- #[ ensures( |& result|
505
- // The resulting pointer should either be unchanged or still point to the same allocation
506
- ( self . addr( ) == result. addr( ) ) ||
507
- ( core:: ub_checks:: same_allocation( self , result) )
496
+ count == 0 ||
497
+ (
498
+ ( core:: mem:: size_of_val_raw( self ) > 0 ) &&
499
+ ( self . addr( ) as isize ) . checked_add( count) . is_some( ) ) &&
500
+ ( core:: ub_checks:: same_allocation( self , self . wrapping_byte_offset( count) )
501
+ )
508
502
) ]
503
+ #[ ensures( |result| core:: mem:: size_of_val_raw( self ) == 0 || core:: ub_checks:: same_allocation( self , * result) ) ]
509
504
pub const unsafe fn byte_offset ( self , count : isize ) -> Self {
510
505
// SAFETY: the caller must uphold the safety contract for `offset`.
511
506
unsafe { self . cast :: < u8 > ( ) . offset ( count) . with_metadata_of ( self ) }
@@ -901,7 +896,7 @@ impl<T: ?Sized> *mut T {
901
896
// Ensuring that both pointers point to the same address or are in the same allocation
902
897
( self as isize == origin as isize || core:: ub_checks:: same_allocation( self , origin) )
903
898
) ]
904
- #[ ensures( |result| * result == ( self as isize - origin as isize ) / ( mem:: size_of:: <T >( ) as isize ) ) ]
899
+ #[ ensures( |result| core :: mem :: size_of :: < T > ( ) == 0 || ( * result == ( self as isize - origin as isize ) / ( mem:: size_of:: <T >( ) as isize ) ) ) ]
905
900
pub const unsafe fn offset_from ( self , origin : * const T ) -> isize
906
901
where
907
902
T : Sized ,
@@ -1087,7 +1082,7 @@ impl<T: ?Sized> *mut T {
1087
1082
// Precondition 2: adding the computed offset to `self` does not cause overflow.
1088
1083
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
1089
1084
count. checked_mul( core:: mem:: size_of:: <T >( ) )
1090
- . map_or ( false , |computed_offset| {
1085
+ . is_some_and ( |computed_offset| {
1091
1086
computed_offset <= isize :: MAX as usize && ( self as isize ) . checked_add( computed_offset as isize ) . is_some( )
1092
1087
} ) &&
1093
1088
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1154,17 +1149,17 @@ impl<T: ?Sized> *mut T {
1154
1149
#[ requires(
1155
1150
// If count is zero, any pointer is valid including null pointer.
1156
1151
( count == 0 ) ||
1157
- // Else if count is not zero, then ensure that subtracting `count` doesn't
1158
- // cause overflow and that both pointers `self` and the result are in the
1159
- // same allocation.
1160
- ( ( self . addr( ) as isize ) . checked_add( count as isize ) . is_some( ) &&
1161
- core:: ub_checks:: same_allocation( self , self . wrapping_byte_add( count) ) )
1162
- ) ]
1163
- #[ ensures( |& result|
1164
- // The resulting pointer should either be unchanged or still point to the same allocation
1165
- ( self . addr( ) == result. addr( ) ) ||
1166
- ( core:: ub_checks:: same_allocation( self , result) )
1152
+ // Else if count is not zero, then ensure that adding `count` doesn't cause
1153
+ // overflow and that both pointers `self` and the result are in the same
1154
+ // allocation
1155
+ (
1156
+ ( count <= isize :: MAX as usize ) &&
1157
+ ( core:: mem:: size_of_val_raw( self ) > 0 ) &&
1158
+ ( ( self . addr( ) as isize ) . checked_add( count as isize ) . is_some( ) ) &&
1159
+ ( core:: ub_checks:: same_allocation( self , self . wrapping_byte_add( count) ) )
1160
+ )
1167
1161
) ]
1162
+ #[ ensures( |result| core:: mem:: size_of_val_raw( self ) == 0 || core:: ub_checks:: same_allocation( self , * result) ) ]
1168
1163
pub const unsafe fn byte_add ( self , count : usize ) -> Self {
1169
1164
// SAFETY: the caller must uphold the safety contract for `add`.
1170
1165
unsafe { self . cast :: < u8 > ( ) . add ( count) . with_metadata_of ( self ) }
@@ -1227,7 +1222,7 @@ impl<T: ?Sized> *mut T {
1227
1222
// Precondition 2: substracting the computed offset from `self` does not cause overflow.
1228
1223
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
1229
1224
count. checked_mul( core:: mem:: size_of:: <T >( ) )
1230
- . map_or ( false , |computed_offset| {
1225
+ . is_some_and ( |computed_offset| {
1231
1226
computed_offset <= isize :: MAX as usize && ( self as isize ) . checked_sub( computed_offset as isize ) . is_some( )
1232
1227
} ) &&
1233
1228
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1303,14 +1298,14 @@ impl<T: ?Sized> *mut T {
1303
1298
// Else if count is not zero, then ensure that subtracting `count` doesn't
1304
1299
// cause overflow and that both pointers `self` and the result are in the
1305
1300
// same allocation.
1306
- ( ( self . addr( ) as isize ) . checked_sub( count as isize ) . is_some( ) &&
1307
- core:: ub_checks:: same_allocation( self , self . wrapping_byte_sub( count) ) )
1308
- ) ]
1309
- #[ ensures( |& result|
1310
- // The resulting pointer should either be unchanged or still point to the same allocation
1311
- ( self . addr( ) == result. addr( ) ) ||
1312
- ( core:: ub_checks:: same_allocation( self , result) )
1301
+ (
1302
+ ( count <= isize :: MAX as usize ) &&
1303
+ ( core:: mem:: size_of_val_raw( self ) > 0 ) &&
1304
+ ( ( self . addr( ) as isize ) . checked_sub( count as isize ) . is_some( ) ) &&
1305
+ ( core:: ub_checks:: same_allocation( self , self . wrapping_byte_sub( count) ) )
1306
+ )
1313
1307
) ]
1308
+ #[ ensures( |result| core:: mem:: size_of_val_raw( self ) == 0 || core:: ub_checks:: same_allocation( self , * result) ) ]
1314
1309
pub const unsafe fn byte_sub ( self , count : usize ) -> Self {
1315
1310
// SAFETY: the caller must uphold the safety contract for `sub`.
1316
1311
unsafe { self . cast :: < u8 > ( ) . sub ( count) . with_metadata_of ( self ) }
@@ -2670,7 +2665,6 @@ mod verify {
2670
2665
) ;
2671
2666
2672
2667
#[ kani:: proof_for_contract( <* mut ( ) >:: byte_offset) ]
2673
- #[ kani:: should_panic]
2674
2668
pub fn check_mut_byte_offset_unit_invalid_count ( ) {
2675
2669
let mut val = ( ) ;
2676
2670
let ptr: * mut ( ) = & mut val;
@@ -2701,7 +2695,7 @@ mod verify {
2701
2695
pub fn $proof_name( ) {
2702
2696
let mut val = ( ) ;
2703
2697
let ptr: * mut ( ) = & mut val;
2704
- let count: isize = mem :: size_of :: < ( ) > ( ) as isize ;
2698
+ let count: isize = kani :: any ( ) ;
2705
2699
unsafe {
2706
2700
ptr. byte_offset( count) ;
2707
2701
}
@@ -2714,7 +2708,7 @@ mod verify {
2714
2708
let mut val = ( ) ;
2715
2709
let ptr: * mut ( ) = & mut val;
2716
2710
//byte_add and byte_sub need count to be usize unlike byte_offset
2717
- let count: usize = mem :: size_of :: < ( ) > ( ) ;
2711
+ let count: usize = kani :: any ( ) ;
2718
2712
unsafe {
2719
2713
ptr. $fn_name( count) ;
2720
2714
}
0 commit comments