@@ -394,6 +394,37 @@ impl<T: ?Sized> *const T {
394394 where
395395 T : Sized ,
396396 {
397+ #[ inline]
398+ const fn runtime_offset_nowrap ( this : * const ( ) , count : isize , size : usize ) -> bool {
399+ #[ inline]
400+ fn runtime ( this : * const ( ) , count : isize , size : usize ) -> bool {
401+ let Some ( byte_offset) = count. checked_mul ( size as isize ) else {
402+ return false ;
403+ } ;
404+ if byte_offset < 0 {
405+ -byte_offset as usize <= this. addr ( )
406+ } else {
407+ this. addr ( ) . checked_add ( byte_offset as usize ) . is_some ( )
408+ }
409+ }
410+
411+ const fn comptime ( _: * const ( ) , _: isize , _: usize ) -> bool {
412+ true
413+ }
414+
415+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
416+ }
417+
418+ ub_checks:: assert_unsafe_precondition!(
419+ check_language_ub,
420+ "ptr::offset requires the address calculation to not overflow" ,
421+ (
422+ this: * const ( ) = self as * const ( ) ,
423+ count: isize = count,
424+ size: usize = size_of:: <T >( ) ,
425+ ) => runtime_offset_nowrap( this, count, size)
426+ ) ;
427+
397428 // SAFETY: the caller must uphold the safety contract for `offset`.
398429 unsafe { intrinsics:: offset ( self , count) }
399430 }
@@ -728,7 +759,6 @@ impl<T: ?Sized> *const T {
728759 true
729760 }
730761
731- #[ allow( unused_unsafe) ]
732762 intrinsics:: const_eval_select ( ( this, origin) , comptime, runtime)
733763 }
734764
@@ -855,6 +885,33 @@ impl<T: ?Sized> *const T {
855885 where
856886 T : Sized ,
857887 {
888+ #[ inline]
889+ const fn runtime_add_nowrap ( this : * const ( ) , count : usize , size : usize ) -> bool {
890+ #[ inline]
891+ fn runtime ( this : * const ( ) , count : usize , size : usize ) -> bool {
892+ let Some ( byte_offset) = count. checked_mul ( size) else {
893+ return false ;
894+ } ;
895+ this. addr ( ) . checked_add ( byte_offset as usize ) . is_some ( )
896+ }
897+
898+ const fn comptime ( _: * const ( ) , _: usize , _: usize ) -> bool {
899+ true
900+ }
901+
902+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
903+ }
904+
905+ ub_checks:: assert_unsafe_precondition!(
906+ check_language_ub,
907+ "ptr::add requires that the address calculation does not overflow" ,
908+ (
909+ this: * const ( ) = self as * const ( ) ,
910+ count: usize = count,
911+ size: usize = size_of:: <T >( ) ,
912+ ) => runtime_add_nowrap( this, count, size)
913+ ) ;
914+
858915 // SAFETY: the caller must uphold the safety contract for `offset`.
859916 unsafe { intrinsics:: offset ( self , count) }
860917 }
@@ -930,6 +987,33 @@ impl<T: ?Sized> *const T {
930987 where
931988 T : Sized ,
932989 {
990+ #[ inline]
991+ const fn runtime_sub_nowrap ( this : * const ( ) , count : usize , size : usize ) -> bool {
992+ #[ inline]
993+ fn runtime ( this : * const ( ) , count : usize , size : usize ) -> bool {
994+ let Some ( byte_offset) = count. checked_mul ( size) else {
995+ return false ;
996+ } ;
997+ this. addr ( ) >= byte_offset
998+ }
999+
1000+ const fn comptime ( _: * const ( ) , _: usize , _: usize ) -> bool {
1001+ true
1002+ }
1003+
1004+ intrinsics:: const_eval_select ( ( this, count, size) , comptime, runtime)
1005+ }
1006+
1007+ ub_checks:: assert_unsafe_precondition!(
1008+ check_language_ub,
1009+ "ptr::sub requires that the address calculation does not overflow" ,
1010+ (
1011+ this: * const ( ) = self as * const ( ) ,
1012+ count: usize = count,
1013+ size: usize = size_of:: <T >( ) ,
1014+ ) => runtime_sub_nowrap( this, count, size)
1015+ ) ;
1016+
9331017 if T :: IS_ZST {
9341018 // Pointer arithmetic does nothing when the pointee is a ZST.
9351019 self
0 commit comments