@@ -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
} ;
@@ -2345,7 +2345,7 @@ macro_rules! iterator {
2345
2345
unsafe fn post_inc_start( & mut self , offset: isize ) -> * $raw_mut T {
2346
2346
if mem:: size_of:: <T >( ) == 0 {
2347
2347
// This is *reducing* the length. `ptr` never changes with ZST.
2348
- self . end = ( self . end as isize ) . wrapping_sub ( offset) as * $raw_mut T ;
2348
+ self . end = ( self . end as * $raw_mut u8 ) . wrapping_offset ( - offset) as * $raw_mut T ;
2349
2349
self . ptr
2350
2350
} else {
2351
2351
let old = self . ptr;
@@ -2360,7 +2360,7 @@ macro_rules! iterator {
2360
2360
#[ inline( always) ]
2361
2361
unsafe fn pre_dec_end( & mut self , offset: isize ) -> * $raw_mut T {
2362
2362
if mem:: size_of:: <T >( ) == 0 {
2363
- self . end = ( self . end as isize ) . wrapping_sub ( offset) as * $raw_mut T ;
2363
+ self . end = ( self . end as * $raw_mut u8 ) . wrapping_offset ( - offset) as * $raw_mut T ;
2364
2364
self . ptr
2365
2365
} else {
2366
2366
self . end = self . end. offset( -offset) ;
@@ -2423,12 +2423,14 @@ macro_rules! iterator {
2423
2423
#[ inline]
2424
2424
fn nth( & mut self , n: usize ) -> Option <$elem> {
2425
2425
if n >= self . len( ) {
2426
- // This iterator is now empty. The way we encode the length of a non-ZST
2427
- // iterator, this works for both ZST and non-ZST.
2428
- // For a ZST we would usually do `self.end = self.ptr`, but since
2429
- // we will not give out an reference any more after this there is no
2430
- // way to observe the difference except for raw pointers.
2431
- self . ptr = self . end;
2426
+ // This iterator is now empty.
2427
+ if mem:: size_of:: <T >( ) == 0 {
2428
+ // We have to do it this way as `ptr` may never be 0, but `end`
2429
+ // could be (due to wrapping).
2430
+ self . end = self . ptr;
2431
+ } else {
2432
+ self . ptr = self . end;
2433
+ }
2432
2434
return None ;
2433
2435
}
2434
2436
// We are in bounds. `offset` does the right thing even for ZSTs.
0 commit comments