@@ -394,6 +394,35 @@ impl<T: ?Sized> *const T {
394394 where
395395 T : Sized ,
396396 {
397+ const fn runtime_offset_nowrap ( this : * const ( ) , count : isize , size : usize ) -> bool {
398+ fn runtime ( this : * const ( ) , count : isize , size : usize ) -> bool {
399+ let Some ( byte_offset) = count. checked_mul ( size as isize ) else {
400+ return false ;
401+ } ;
402+ if byte_offset < 0 {
403+ -byte_offset as usize <= this. addr ( )
404+ } else {
405+ this. addr ( ) . checked_add ( byte_offset as usize ) . is_some ( )
406+ }
407+ }
408+
409+ const fn comptime ( _: * const ( ) , _: isize , _: usize ) -> bool {
410+ true
411+ }
412+
413+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
414+ }
415+
416+ ub_checks:: assert_unsafe_precondition!(
417+ check_language_ub,
418+ "ptr::offset requires the address calculation to not overflow" ,
419+ (
420+ this: * const ( ) = self as * const ( ) ,
421+ count: isize = count,
422+ size: usize = size_of:: <T >( ) ,
423+ ) => runtime_offset_nowrap( this, count, size)
424+ ) ;
425+
397426 // SAFETY: the caller must uphold the safety contract for `offset`.
398427 unsafe { intrinsics:: offset ( self , count) }
399428 }
@@ -728,7 +757,6 @@ impl<T: ?Sized> *const T {
728757 true
729758 }
730759
731- #[ allow( unused_unsafe) ]
732760 intrinsics:: const_eval_select ( ( this, origin) , comptime, runtime)
733761 }
734762
@@ -855,6 +883,31 @@ impl<T: ?Sized> *const T {
855883 where
856884 T : Sized ,
857885 {
886+ const fn runtime_add_nowrap ( this : * const ( ) , count : usize , size : usize ) -> bool {
887+ fn runtime ( this : * const ( ) , count : usize , size : usize ) -> bool {
888+ let Some ( byte_offset) = count. checked_mul ( size) else {
889+ return false ;
890+ } ;
891+ this. addr ( ) . checked_add ( byte_offset as usize ) . is_some ( )
892+ }
893+
894+ const fn comptime ( _: * const ( ) , _: usize , _: usize ) -> bool {
895+ true
896+ }
897+
898+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
899+ }
900+
901+ ub_checks:: assert_unsafe_precondition!(
902+ check_language_ub,
903+ "ptr::add requires that the address calculation does not overflow" ,
904+ (
905+ this: * const ( ) = self as * const ( ) ,
906+ count: usize = count,
907+ size: usize = size_of:: <T >( ) ,
908+ ) => runtime_add_nowrap( this, count, size)
909+ ) ;
910+
858911 // SAFETY: the caller must uphold the safety contract for `offset`.
859912 unsafe { intrinsics:: offset ( self , count) }
860913 }
@@ -930,6 +983,31 @@ impl<T: ?Sized> *const T {
930983 where
931984 T : Sized ,
932985 {
986+ const fn runtime_sub_nowrap ( this : * const ( ) , count : usize , size : usize ) -> bool {
987+ fn runtime ( this : * const ( ) , count : usize , size : usize ) -> bool {
988+ let Some ( byte_offset) = count. checked_mul ( size) else {
989+ return false ;
990+ } ;
991+ this. addr ( ) >= byte_offset
992+ }
993+
994+ const fn comptime ( _: * const ( ) , _: usize , _: usize ) -> bool {
995+ true
996+ }
997+
998+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
999+ }
1000+
1001+ ub_checks:: assert_unsafe_precondition!(
1002+ check_language_ub,
1003+ "ptr::sub requires that the address calculation does not overflow" ,
1004+ (
1005+ this: * const ( ) = self as * const ( ) ,
1006+ count: usize = count,
1007+ size: usize = size_of:: <T >( ) ,
1008+ ) => runtime_sub_nowrap( this, count, size)
1009+ ) ;
1010+
9331011 if T :: IS_ZST {
9341012 // Pointer arithmetic does nothing when the pointee is a ZST.
9351013 self
0 commit comments