@@ -511,6 +511,7 @@ macro_rules! int_impl {
511
511
without modifying the original"]
512
512
#[ inline( always) ]
513
513
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
514
+ #[ requires( !self . overflowing_add( rhs) . 1 ) ]
514
515
pub const unsafe fn unchecked_add( self , rhs: Self ) -> Self {
515
516
assert_unsafe_precondition!(
516
517
check_language_ub,
@@ -663,6 +664,7 @@ macro_rules! int_impl {
663
664
without modifying the original"]
664
665
#[ inline( always) ]
665
666
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
667
+ #[ requires( !self . overflowing_sub( rhs) . 1 ) ] // Preconditions: No overflow should occur
666
668
pub const unsafe fn unchecked_sub( self , rhs: Self ) -> Self {
667
669
assert_unsafe_precondition!(
668
670
check_language_ub,
@@ -815,6 +817,7 @@ macro_rules! int_impl {
815
817
without modifying the original"]
816
818
#[ inline( always) ]
817
819
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
820
+ #[ requires( !self . overflowing_mul( rhs) . 1 ) ]
818
821
pub const unsafe fn unchecked_mul( self , rhs: Self ) -> Self {
819
822
assert_unsafe_precondition!(
820
823
check_language_ub,
@@ -1164,6 +1167,8 @@ macro_rules! int_impl {
1164
1167
#[ rustc_const_unstable( feature = "unchecked_neg" , issue = "85122" ) ]
1165
1168
#[ inline( always) ]
1166
1169
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
1170
+ #[ requires( self != $SelfT:: MIN ) ]
1171
+ #[ ensures( |result| * result == -self ) ]
1167
1172
pub const unsafe fn unchecked_neg( self ) -> Self {
1168
1173
assert_unsafe_precondition!(
1169
1174
check_language_ub,
@@ -1297,6 +1302,7 @@ macro_rules! int_impl {
1297
1302
#[ rustc_const_unstable( feature = "unchecked_shifts" , issue = "85122" ) ]
1298
1303
#[ inline( always) ]
1299
1304
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
1305
+ #[ requires( rhs < <$ActualT>:: BITS ) ]
1300
1306
pub const unsafe fn unchecked_shl( self , rhs: u32 ) -> Self {
1301
1307
assert_unsafe_precondition!(
1302
1308
check_language_ub,
@@ -1423,6 +1429,7 @@ macro_rules! int_impl {
1423
1429
#[ rustc_const_unstable( feature = "unchecked_shifts" , issue = "85122" ) ]
1424
1430
#[ inline( always) ]
1425
1431
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
1432
+ #[ requires( rhs < <$ActualT>:: BITS ) ] // i.e. requires the right hand side of the shift (rhs) to be less than the number of bits in the type. This prevents undefined behavior.
1426
1433
pub const unsafe fn unchecked_shr( self , rhs: u32 ) -> Self {
1427
1434
assert_unsafe_precondition!(
1428
1435
check_language_ub,
@@ -2153,6 +2160,7 @@ macro_rules! int_impl {
2153
2160
without modifying the original"]
2154
2161
#[ inline( always) ]
2155
2162
#[ rustc_allow_const_fn_unstable( unchecked_shifts) ]
2163
+ #[ ensures( |result| * result == self << ( rhs & ( Self :: BITS - 1 ) ) ) ]
2156
2164
pub const fn wrapping_shl( self , rhs: u32 ) -> Self {
2157
2165
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
2158
2166
// out of bounds
@@ -2183,6 +2191,7 @@ macro_rules! int_impl {
2183
2191
without modifying the original"]
2184
2192
#[ inline( always) ]
2185
2193
#[ rustc_allow_const_fn_unstable( unchecked_shifts) ]
2194
+ #[ ensures( |result| * result == self >> ( rhs & ( Self :: BITS - 1 ) ) ) ]
2186
2195
pub const fn wrapping_shr( self , rhs: u32 ) -> Self {
2187
2196
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
2188
2197
// out of bounds
0 commit comments