Skip to content

Commit cbdba2b

Browse files
committed
use wrapping_offset; fix logic error in nth
1 parent c7d90d1 commit cbdba2b

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/libcore/slice/mod.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ impl<T> [T] {
546546
assume(!ptr.is_null());
547547

548548
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
550550
} else {
551551
ptr.offset(self.len() as isize)
552552
};
@@ -578,7 +578,7 @@ impl<T> [T] {
578578
assume(!ptr.is_null());
579579

580580
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
582582
} else {
583583
ptr.offset(self.len() as isize)
584584
};
@@ -2354,7 +2354,7 @@ macro_rules! iterator {
23542354
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
23552355
if mem::size_of::<T>() == 0 {
23562356
// 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;
23582358
self.ptr
23592359
} else {
23602360
let old = self.ptr;
@@ -2369,7 +2369,7 @@ macro_rules! iterator {
23692369
#[inline(always)]
23702370
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
23712371
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;
23732373
self.ptr
23742374
} else {
23752375
self.end = self.end.offset(-offset);
@@ -2432,12 +2432,14 @@ macro_rules! iterator {
24322432
#[inline]
24332433
fn nth(&mut self, n: usize) -> Option<$elem> {
24342434
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+
}
24412443
return None;
24422444
}
24432445
// We are in bounds. `offset` does the right thing even for ZSTs.

0 commit comments

Comments
 (0)