@@ -475,9 +475,15 @@ macro_rules! int_impl {
475
475
#[ inline( always) ]
476
476
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
477
477
pub const unsafe fn unchecked_add( self , rhs: Self ) -> Self {
478
- // SAFETY: the caller must uphold the safety contract for
479
- // `unchecked_add`.
480
- unsafe { intrinsics:: unchecked_add( self , rhs) }
478
+ // SAFETY: this is guaranteed to be safe by the caller.
479
+ unsafe {
480
+ let lhs = self ;
481
+ intrinsics:: assert_unsafe_precondition!(
482
+ concat!( stringify!( $SelfT) , "::unchecked_add cannot overflow" ) ,
483
+ ( lhs: $SelfT, rhs: $SelfT) => !lhs. overflowing_add( rhs) . 1
484
+ ) ;
485
+ intrinsics:: unchecked_add( lhs, rhs)
486
+ }
481
487
}
482
488
483
489
/// Checked addition with an unsigned integer. Computes `self + rhs`,
@@ -543,9 +549,15 @@ macro_rules! int_impl {
543
549
#[ inline( always) ]
544
550
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
545
551
pub const unsafe fn unchecked_sub( self , rhs: Self ) -> Self {
546
- // SAFETY: the caller must uphold the safety contract for
547
- // `unchecked_sub`.
548
- unsafe { intrinsics:: unchecked_sub( self , rhs) }
552
+ // SAFETY: this is guaranteed to be safe by the caller.
553
+ unsafe {
554
+ let lhs = self ;
555
+ intrinsics:: assert_unsafe_precondition!(
556
+ concat!( stringify!( $SelfT) , "::unchecked_sub cannot overflow" ) ,
557
+ ( lhs: $SelfT, rhs: $SelfT) => !lhs. overflowing_sub( rhs) . 1
558
+ ) ;
559
+ intrinsics:: unchecked_sub( lhs, rhs)
560
+ }
549
561
}
550
562
551
563
/// Checked subtraction with an unsigned integer. Computes `self - rhs`,
@@ -611,9 +623,15 @@ macro_rules! int_impl {
611
623
#[ inline( always) ]
612
624
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
613
625
pub const unsafe fn unchecked_mul( self , rhs: Self ) -> Self {
614
- // SAFETY: the caller must uphold the safety contract for
615
- // `unchecked_mul`.
616
- unsafe { intrinsics:: unchecked_mul( self , rhs) }
626
+ // SAFETY: this is guaranteed to be safe by the caller.
627
+ unsafe {
628
+ let lhs = self ;
629
+ intrinsics:: assert_unsafe_precondition!(
630
+ concat!( stringify!( $SelfT) , "::unchecked_mul cannot overflow" ) ,
631
+ ( lhs: $SelfT, rhs: $SelfT) => !lhs. overflowing_mul( rhs) . 1
632
+ ) ;
633
+ intrinsics:: unchecked_mul( lhs, rhs)
634
+ }
617
635
}
618
636
619
637
/// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
@@ -760,9 +778,15 @@ macro_rules! int_impl {
760
778
#[ inline( always) ]
761
779
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
762
780
pub const unsafe fn unchecked_neg( self ) -> Self {
763
- // SAFETY: the caller must uphold the safety contract for
764
- // `unchecked_neg`.
765
- unsafe { intrinsics:: unchecked_sub( 0 , self ) }
781
+ // SAFETY: this is guaranteed to be safe by the caller.
782
+ unsafe {
783
+ let n = self ;
784
+ intrinsics:: assert_unsafe_precondition!(
785
+ concat!( stringify!( $SelfT) , "::unchecked_neg cannot overflow" ) ,
786
+ ( n: $SelfT) => !n. overflowing_neg( ) . 1
787
+ ) ;
788
+ intrinsics:: unchecked_sub( 0 , n)
789
+ }
766
790
}
767
791
768
792
/// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
@@ -807,10 +831,17 @@ macro_rules! int_impl {
807
831
#[ inline( always) ]
808
832
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
809
833
pub const unsafe fn unchecked_shl( self , rhs: u32 ) -> Self {
810
- // SAFETY: the caller must uphold the safety contract for
811
- // `unchecked_shl`.
834
+ // SAFETY: this is guaranteed to be safe by the caller.
812
835
// Any legal shift amount is losslessly representable in the self type.
813
- unsafe { intrinsics:: unchecked_shl( self , conv_rhs_for_unchecked_shift!( $SelfT, rhs) ) }
836
+ unsafe {
837
+ let lhs = self ;
838
+ intrinsics:: assert_unsafe_precondition!(
839
+ concat!( stringify!( $SelfT) , "::unchecked_shl cannot overflow" ) ,
840
+ ( lhs: $SelfT, rhs: u32 ) => !lhs. overflowing_shl( rhs) . 1
841
+ ) ;
842
+ let rhs = conv_rhs_for_unchecked_shift!( $SelfT, rhs) ;
843
+ intrinsics:: unchecked_shl( lhs, rhs)
844
+ }
814
845
}
815
846
816
847
/// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
@@ -855,10 +886,17 @@ macro_rules! int_impl {
855
886
#[ inline( always) ]
856
887
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
857
888
pub const unsafe fn unchecked_shr( self , rhs: u32 ) -> Self {
858
- // SAFETY: the caller must uphold the safety contract for
859
- // `unchecked_shr`.
889
+ // SAFETY: this is guaranteed to be safe by the caller.
860
890
// Any legal shift amount is losslessly representable in the self type.
861
- unsafe { intrinsics:: unchecked_shr( self , conv_rhs_for_unchecked_shift!( $SelfT, rhs) ) }
891
+ unsafe {
892
+ let lhs = self ;
893
+ intrinsics:: assert_unsafe_precondition!(
894
+ concat!( stringify!( $SelfT) , "::unchecked_shr cannot overflow" ) ,
895
+ ( lhs: $SelfT, rhs: u32 ) => !lhs. overflowing_shr( rhs) . 1
896
+ ) ;
897
+ let rhs = conv_rhs_for_unchecked_shift!( $SelfT, rhs) ;
898
+ intrinsics:: unchecked_shr( lhs, rhs)
899
+ }
862
900
}
863
901
864
902
/// Checked absolute value. Computes `self.abs()`, returning `None` if
0 commit comments