use wrapping_offset; fix logic error in nth
This commit is contained in:
parent
c7d90d1a50
commit
cbdba2b4c2
|
@ -546,7 +546,7 @@ impl<T> [T] {
|
||||||
assume(!ptr.is_null());
|
assume(!ptr.is_null());
|
||||||
|
|
||||||
let end = if mem::size_of::<T>() == 0 {
|
let end = if mem::size_of::<T>() == 0 {
|
||||||
(ptr as usize).wrapping_add(self.len()) as *const _
|
(ptr as *const u8).wrapping_offset(self.len() as isize) as *const T
|
||||||
} else {
|
} else {
|
||||||
ptr.offset(self.len() as isize)
|
ptr.offset(self.len() as isize)
|
||||||
};
|
};
|
||||||
|
@ -578,7 +578,7 @@ impl<T> [T] {
|
||||||
assume(!ptr.is_null());
|
assume(!ptr.is_null());
|
||||||
|
|
||||||
let end = if mem::size_of::<T>() == 0 {
|
let end = if mem::size_of::<T>() == 0 {
|
||||||
(ptr as usize).wrapping_add(self.len()) as *mut _
|
(ptr as *mut u8).wrapping_offset(self.len() as isize) as *mut T
|
||||||
} else {
|
} else {
|
||||||
ptr.offset(self.len() as isize)
|
ptr.offset(self.len() as isize)
|
||||||
};
|
};
|
||||||
|
@ -2354,7 +2354,7 @@ macro_rules! iterator {
|
||||||
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
|
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
|
||||||
if mem::size_of::<T>() == 0 {
|
if mem::size_of::<T>() == 0 {
|
||||||
// This is *reducing* the length. `ptr` never changes with ZST.
|
// This is *reducing* the length. `ptr` never changes with ZST.
|
||||||
self.end = (self.end as isize).wrapping_sub(offset) as * $raw_mut T;
|
self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T;
|
||||||
self.ptr
|
self.ptr
|
||||||
} else {
|
} else {
|
||||||
let old = self.ptr;
|
let old = self.ptr;
|
||||||
|
@ -2369,7 +2369,7 @@ macro_rules! iterator {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
|
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
|
||||||
if mem::size_of::<T>() == 0 {
|
if mem::size_of::<T>() == 0 {
|
||||||
self.end = (self.end as isize).wrapping_sub(offset) as * $raw_mut T;
|
self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T;
|
||||||
self.ptr
|
self.ptr
|
||||||
} else {
|
} else {
|
||||||
self.end = self.end.offset(-offset);
|
self.end = self.end.offset(-offset);
|
||||||
|
@ -2432,12 +2432,14 @@ macro_rules! iterator {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn nth(&mut self, n: usize) -> Option<$elem> {
|
fn nth(&mut self, n: usize) -> Option<$elem> {
|
||||||
if n >= self.len() {
|
if n >= self.len() {
|
||||||
// This iterator is now empty. The way we encode the length of a non-ZST
|
// This iterator is now empty.
|
||||||
// iterator, this works for both ZST and non-ZST.
|
if mem::size_of::<T>() == 0 {
|
||||||
// For a ZST we would usually do `self.end = self.ptr`, but since
|
// We have to do it this way as `ptr` may never be 0, but `end`
|
||||||
// we will not give out an reference any more after this there is no
|
// could be (due to wrapping).
|
||||||
// way to observe the difference except for raw pointers.
|
self.end = self.ptr;
|
||||||
self.ptr = self.end;
|
} else {
|
||||||
|
self.ptr = self.end;
|
||||||
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// We are in bounds. `offset` does the right thing even for ZSTs.
|
// We are in bounds. `offset` does the right thing even for ZSTs.
|
||||||
|
|
Loading…
Reference in a new issue