@@ -394,6 +394,35 @@ impl<T: ?Sized> *const T {
394
394
where
395
395
T : Sized ,
396
396
{
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
+
397
426
// SAFETY: the caller must uphold the safety contract for `offset`.
398
427
unsafe { intrinsics:: offset ( self , count) }
399
428
}
@@ -728,7 +757,6 @@ impl<T: ?Sized> *const T {
728
757
true
729
758
}
730
759
731
- #[ allow( unused_unsafe) ]
732
760
intrinsics:: const_eval_select ( ( this, origin) , comptime, runtime)
733
761
}
734
762
@@ -855,6 +883,31 @@ impl<T: ?Sized> *const T {
855
883
where
856
884
T : Sized ,
857
885
{
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
+
858
911
// SAFETY: the caller must uphold the safety contract for `offset`.
859
912
unsafe { intrinsics:: offset ( self , count) }
860
913
}
@@ -930,6 +983,31 @@ impl<T: ?Sized> *const T {
930
983
where
931
984
T : Sized ,
932
985
{
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
+
933
1011
if T :: IS_ZST {
934
1012
// Pointer arithmetic does nothing when the pointee is a ZST.
935
1013
self
0 commit comments