@@ -546,7 +546,7 @@ impl<T> [T] {
546
546
assume ( !ptr. is_null ( ) ) ;
547
547
548
548
let end = if mem:: size_of :: < T > ( ) == 0 {
549
- ( ptr as usize ) . wrapping_add ( self . len ( ) ) as * const _
549
+ ( ptr as * const u8 ) . wrapping_offset ( self . len ( ) as isize ) as * const T
550
550
} else {
551
551
ptr. offset ( self . len ( ) as isize )
552
552
} ;
@@ -578,7 +578,7 @@ impl<T> [T] {
578
578
assume ( !ptr. is_null ( ) ) ;
579
579
580
580
let end = if mem:: size_of :: < T > ( ) == 0 {
581
- ( ptr as usize ) . wrapping_add ( self . len ( ) ) as * mut _
581
+ ( ptr as * mut u8 ) . wrapping_offset ( self . len ( ) as isize ) as * mut T
582
582
} else {
583
583
ptr. offset ( self . len ( ) as isize )
584
584
} ;
@@ -2354,7 +2354,7 @@ macro_rules! iterator {
2354
2354
unsafe fn post_inc_start( & mut self , offset: isize ) -> * $raw_mut T {
2355
2355
if mem:: size_of:: <T >( ) == 0 {
2356
2356
// This is *reducing* the length. `ptr` never changes with ZST.
2357
- self . end = ( self . end as isize ) . wrapping_sub ( offset) as * $raw_mut T ;
2357
+ self . end = ( self . end as * $raw_mut u8 ) . wrapping_offset ( - offset) as * $raw_mut T ;
2358
2358
self . ptr
2359
2359
} else {
2360
2360
let old = self . ptr;
@@ -2369,7 +2369,7 @@ macro_rules! iterator {
2369
2369
#[ inline( always) ]
2370
2370
unsafe fn pre_dec_end( & mut self , offset: isize ) -> * $raw_mut T {
2371
2371
if mem:: size_of:: <T >( ) == 0 {
2372
- self . end = ( self . end as isize ) . wrapping_sub ( offset) as * $raw_mut T ;
2372
+ self . end = ( self . end as * $raw_mut u8 ) . wrapping_offset ( - offset) as * $raw_mut T ;
2373
2373
self . ptr
2374
2374
} else {
2375
2375
self . end = self . end. offset( -offset) ;
@@ -2432,12 +2432,14 @@ macro_rules! iterator {
2432
2432
#[ inline]
2433
2433
fn nth( & mut self , n: usize ) -> Option <$elem> {
2434
2434
if n >= self . len( ) {
2435
- // This iterator is now empty. The way we encode the length of a non-ZST
2436
- // iterator, this works for both ZST and non-ZST.
2437
- // For a ZST we would usually do `self.end = self.ptr`, but since
2438
- // we will not give out an reference any more after this there is no
2439
- // way to observe the difference except for raw pointers.
2440
- self . ptr = self . end;
2435
+ // This iterator is now empty.
2436
+ if mem:: size_of:: <T >( ) == 0 {
2437
+ // We have to do it this way as `ptr` may never be 0, but `end`
2438
+ // could be (due to wrapping).
2439
+ self . end = self . ptr;
2440
+ } else {
2441
+ self . ptr = self . end;
2442
+ }
2441
2443
return None ;
2442
2444
}
2443
2445
// We are in bounds. `offset` does the right thing even for ZSTs.
0 commit comments