@@ -394,6 +394,37 @@ impl<T: ?Sized> *const T {
394
394
where
395
395
T : Sized ,
396
396
{
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
+
397
428
// SAFETY: the caller must uphold the safety contract for `offset`.
398
429
unsafe { intrinsics:: offset ( self , count) }
399
430
}
@@ -728,7 +759,6 @@ impl<T: ?Sized> *const T {
728
759
true
729
760
}
730
761
731
- #[ allow( unused_unsafe) ]
732
762
intrinsics:: const_eval_select ( ( this, origin) , comptime, runtime)
733
763
}
734
764
@@ -855,6 +885,33 @@ impl<T: ?Sized> *const T {
855
885
where
856
886
T : Sized ,
857
887
{
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
+
858
915
// SAFETY: the caller must uphold the safety contract for `offset`.
859
916
unsafe { intrinsics:: offset ( self , count) }
860
917
}
@@ -930,6 +987,33 @@ impl<T: ?Sized> *const T {
930
987
where
931
988
T : Sized ,
932
989
{
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
+
933
1017
if T :: IS_ZST {
934
1018
// Pointer arithmetic does nothing when the pointee is a ZST.
935
1019
self
0 commit comments