@@ -140,7 +140,7 @@ impl<T> SliceExt for [T] {
140
140
assume ( !p. is_null ( ) ) ;
141
141
if mem:: size_of :: < T > ( ) == 0 {
142
142
Iter { ptr : p,
143
- end : ( p as usize + self . len ( ) ) as * const T ,
143
+ end : ( ( p as usize ) . wrapping_add ( self . len ( ) ) ) as * const T ,
144
144
_marker : marker:: PhantomData }
145
145
} else {
146
146
Iter { ptr : p,
@@ -277,7 +277,7 @@ impl<T> SliceExt for [T] {
277
277
assume ( !p. is_null ( ) ) ;
278
278
if mem:: size_of :: < T > ( ) == 0 {
279
279
IterMut { ptr : p,
280
- end : ( p as usize + self . len ( ) ) as * mut T ,
280
+ end : ( ( p as usize ) . wrapping_add ( self . len ( ) ) ) as * mut T ,
281
281
_marker : marker:: PhantomData }
282
282
} else {
283
283
IterMut { ptr : p,
@@ -632,35 +632,17 @@ fn size_from_ptr<T>(_: *const T) -> usize {
632
632
633
633
634
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 {
635
+ macro_rules! slice_offset {
642
636
( $ptr: expr, $by: expr) => { {
643
637
let ptr = $ptr;
644
638
if size_from_ptr( ptr) == 0 {
645
- transmute( ptr as usize + $by)
639
+ transmute( ( ptr as isize ) . wrapping_add ( $by) )
646
640
} else {
647
641
ptr. offset( $by)
648
642
}
649
643
} } ;
650
644
}
651
645
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
-
664
646
macro_rules! slice_ref {
665
647
( $ptr: expr) => { {
666
648
let ptr = $ptr;
@@ -683,22 +665,24 @@ macro_rules! iterator {
683
665
#[ inline]
684
666
fn next( & mut self ) -> Option <$elem> {
685
667
// could be implemented with slices, but this avoids bounds checks
686
- unsafe {
687
- :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
688
- :: intrinsics:: assume( !self . end. is_null( ) ) ;
689
- if self . ptr == self . end {
690
- None
691
- } else {
668
+ if self . ptr == self . end {
669
+ None
670
+ } else {
671
+ unsafe {
672
+ if mem:: size_of:: <T >( ) != 0 {
673
+ :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
674
+ :: intrinsics:: assume( !self . end. is_null( ) ) ;
675
+ }
692
676
let old = self . ptr;
693
- self . ptr = slice_add_offset !( self . ptr, 1 ) ;
677
+ self . ptr = slice_offset !( self . ptr, 1 ) ;
694
678
Some ( slice_ref!( old) )
695
679
}
696
680
}
697
681
}
698
682
699
683
#[ inline]
700
684
fn size_hint( & self ) -> ( usize , Option <usize >) {
701
- let diff = ( self . end as usize ) - ( self . ptr as usize ) ;
685
+ let diff = ( self . end as usize ) . wrapping_sub ( self . ptr as usize ) ;
702
686
let size = mem:: size_of:: <T >( ) ;
703
687
let exact = diff / ( if size == 0 { 1 } else { size} ) ;
704
688
( exact, Some ( exact) )
@@ -726,13 +710,15 @@ macro_rules! iterator {
726
710
#[ inline]
727
711
fn next_back( & mut self ) -> Option <$elem> {
728
712
// could be implemented with slices, but this avoids bounds checks
729
- unsafe {
730
- :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
731
- :: intrinsics:: assume( !self . end. is_null( ) ) ;
732
- if self . end == self . ptr {
733
- None
734
- } else {
735
- self . end = slice_sub_offset!( self . end, 1 ) ;
713
+ if self . end == self . ptr {
714
+ None
715
+ } else {
716
+ unsafe {
717
+ self . end = slice_offset!( self . end, -1 ) ;
718
+ if mem:: size_of:: <T >( ) != 0 {
719
+ :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
720
+ :: intrinsics:: assume( !self . end. is_null( ) ) ;
721
+ }
736
722
Some ( slice_ref!( self . end) )
737
723
}
738
724
}
@@ -742,29 +728,29 @@ macro_rules! iterator {
742
728
}
743
729
744
730
macro_rules! make_slice {
745
- ( $t: ty => $result: ty: $start: expr, $end: expr) => { {
746
- let diff = $end as usize - $start as usize ;
747
- let len = if mem:: size_of:: <T >( ) == 0 {
748
- diff
731
+ ( $start: expr, $end: expr) => { {
732
+ let start = $start;
733
+ let diff = ( $end as usize ) . wrapping_sub( start as usize ) ;
734
+ if size_from_ptr( start) == 0 {
735
+ // use a non-null pointer value
736
+ unsafe { from_raw_parts( 1 as * const _, diff) }
749
737
} else {
750
- diff / mem:: size_of:: <$t>( )
751
- } ;
752
- unsafe {
753
- from_raw_parts( $start, len)
738
+ let len = diff / size_from_ptr( start) ;
739
+ unsafe { from_raw_parts( start, len) }
754
740
}
755
741
} }
756
742
}
757
743
758
744
macro_rules! make_mut_slice {
759
- ( $t: ty => $result: ty: $start: expr, $end: expr) => { {
760
- let diff = $end as usize - $start as usize ;
761
- let len = if mem:: size_of:: <T >( ) == 0 {
762
- diff
745
+ ( $start: expr, $end: expr) => { {
746
+ let start = $start;
747
+ let diff = ( $end as usize ) . wrapping_sub( start as usize ) ;
748
+ if size_from_ptr( start) == 0 {
749
+ // use a non-null pointer value
750
+ unsafe { from_raw_parts_mut( 1 as * mut _, diff) }
763
751
} else {
764
- diff / mem:: size_of:: <$t>( )
765
- } ;
766
- unsafe {
767
- from_raw_parts_mut( $start, len)
752
+ let len = diff / size_from_ptr( start) ;
753
+ unsafe { from_raw_parts_mut( start, len) }
768
754
}
769
755
} }
770
756
}
@@ -787,14 +773,14 @@ impl<'a, T> Iter<'a, T> {
787
773
/// iterator can continue to be used while this exists.
788
774
#[ unstable( feature = "core" ) ]
789
775
pub fn as_slice ( & self ) -> & ' a [ T ] {
790
- make_slice ! ( T => & ' a [ T ] : self . ptr, self . end)
776
+ make_slice ! ( self . ptr, self . end)
791
777
}
792
778
793
779
// Helper function for Iter::nth
794
780
fn iter_nth ( & mut self , n : usize ) -> Option < & ' a T > {
795
781
match self . as_slice ( ) . get ( n) {
796
782
Some ( elem_ref) => unsafe {
797
- self . ptr = slice_add_offset ! ( elem_ref as * const _ , 1 ) ;
783
+ self . ptr = slice_offset ! ( self . ptr , ( n as isize ) . wrapping_add ( 1 ) ) ;
798
784
Some ( slice_ref ! ( elem_ref) )
799
785
} ,
800
786
None => {
@@ -827,12 +813,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
827
813
fn idx ( & mut self , index : usize ) -> Option < & ' a T > {
828
814
unsafe {
829
815
if index < self . indexable ( ) {
830
- if mem:: size_of :: < T > ( ) == 0 {
831
- // Use a non-null pointer value
832
- Some ( & mut * ( 1 as * mut _ ) )
833
- } else {
834
- Some ( transmute ( self . ptr . offset ( index as isize ) ) )
835
- }
816
+ Some ( slice_ref ! ( self . ptr. offset( index as isize ) ) )
836
817
} else {
837
818
None
838
819
}
@@ -860,14 +841,14 @@ impl<'a, T> IterMut<'a, T> {
860
841
/// restricted lifetimes that do not consume the iterator.
861
842
#[ unstable( feature = "core" ) ]
862
843
pub fn into_slice ( self ) -> & ' a mut [ T ] {
863
- make_mut_slice ! ( T => & ' a mut [ T ] : self . ptr, self . end)
844
+ make_mut_slice ! ( self . ptr, self . end)
864
845
}
865
846
866
847
// Helper function for IterMut::nth
867
848
fn iter_nth ( & mut self , n : usize ) -> Option < & ' a mut T > {
868
- match make_mut_slice ! ( T => & ' a mut [ T ] : self . ptr, self . end) . get_mut ( n) {
849
+ match make_mut_slice ! ( self . ptr, self . end) . get_mut ( n) {
869
850
Some ( elem_ref) => unsafe {
870
- self . ptr = slice_add_offset ! ( elem_ref as * mut _ , 1 ) ;
851
+ self . ptr = slice_offset ! ( self . ptr , ( n as isize ) . wrapping_add ( 1 ) ) ;
871
852
Some ( slice_ref ! ( elem_ref) )
872
853
} ,
873
854
None => {
0 commit comments