@@ -631,8 +631,14 @@ fn size_from_ptr<T>(_: *const T) -> usize {
631
631
}
632
632
633
633
634
- // Use macro to be generic over const/mut
635
- macro_rules! slice_offset {
634
+ // Use macros to be generic over const/mut
635
+ //
636
+ // They require non-negative `$by` because otherwise the expression
637
+ // `(ptr as usize + $by)` would interpret `-1` as `usize::MAX` (and
638
+ // thus trigger a panic when overflow checks are on).
639
+
640
+ // Use this to do `$ptr + $by`, where `$by` is non-negative.
641
+ macro_rules! slice_add_offset {
636
642
( $ptr: expr, $by: expr) => { {
637
643
let ptr = $ptr;
638
644
if size_from_ptr( ptr) == 0 {
@@ -643,6 +649,18 @@ macro_rules! slice_offset {
643
649
} } ;
644
650
}
645
651
652
+ // Use this to do `$ptr - $by`, where `$by` is non-negative.
653
+ macro_rules! slice_sub_offset {
654
+ ( $ptr: expr, $by: expr) => { {
655
+ let ptr = $ptr;
656
+ if size_from_ptr( ptr) == 0 {
657
+ transmute( ptr as usize - $by)
658
+ } else {
659
+ ptr. offset( -$by)
660
+ }
661
+ } } ;
662
+ }
663
+
646
664
macro_rules! slice_ref {
647
665
( $ptr: expr) => { {
648
666
let ptr = $ptr;
@@ -672,7 +690,7 @@ macro_rules! iterator {
672
690
None
673
691
} else {
674
692
let old = self . ptr;
675
- self . ptr = slice_offset !( self . ptr, 1 ) ;
693
+ self . ptr = slice_add_offset !( self . ptr, 1 ) ;
676
694
Some ( slice_ref!( old) )
677
695
}
678
696
}
@@ -714,7 +732,7 @@ macro_rules! iterator {
714
732
if self . end == self . ptr {
715
733
None
716
734
} else {
717
- self . end = slice_offset !( self . end, - 1 ) ;
735
+ self . end = slice_sub_offset !( self . end, 1 ) ;
718
736
Some ( slice_ref!( self . end) )
719
737
}
720
738
}
@@ -816,7 +834,7 @@ impl<'a, T> Iter<'a, T> {
816
834
fn iter_nth ( & mut self , n : usize ) -> Option < & ' a T > {
817
835
match self . as_slice ( ) . get ( n) {
818
836
Some ( elem_ref) => unsafe {
819
- self . ptr = slice_offset ! ( elem_ref as * const _, 1 ) ;
837
+ self . ptr = slice_add_offset ! ( elem_ref as * const _, 1 ) ;
820
838
Some ( slice_ref ! ( elem_ref) )
821
839
} ,
822
840
None => {
@@ -959,7 +977,7 @@ impl<'a, T> IterMut<'a, T> {
959
977
fn iter_nth ( & mut self , n : usize ) -> Option < & ' a mut T > {
960
978
match make_mut_slice ! ( T => & ' a mut [ T ] : self . ptr, self . end) . get_mut ( n) {
961
979
Some ( elem_ref) => unsafe {
962
- self . ptr = slice_offset ! ( elem_ref as * mut _, 1 ) ;
980
+ self . ptr = slice_add_offset ! ( elem_ref as * mut _, 1 ) ;
963
981
Some ( slice_ref ! ( elem_ref) )
964
982
} ,
965
983
None => {
0 commit comments