fix issues pointed out in review
This commit is contained in:
parent
6654a0bbdc
commit
ffd7ade203
@ -164,18 +164,19 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
||||||
let step_size = self.len().min(n);
|
let step_size = self.len().min(n);
|
||||||
|
let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
|
||||||
if mem::size_of::<T>() == 0 {
|
if mem::size_of::<T>() == 0 {
|
||||||
// SAFETY: due to unchecked casts of unsigned amounts to signed offsets the wraparound
|
// SAFETY: due to unchecked casts of unsigned amounts to signed offsets the wraparound
|
||||||
// effectively results in unsigned pointers representing positions 0..usize::MAX,
|
// effectively results in unsigned pointers representing positions 0..usize::MAX,
|
||||||
// which is valid for ZSTs.
|
// which is valid for ZSTs.
|
||||||
self.ptr = unsafe { arith_offset(self.ptr as *const i8, step_size as isize) as *mut T }
|
self.ptr = unsafe { arith_offset(self.ptr as *const i8, step_size as isize) as *mut T }
|
||||||
} else {
|
} else {
|
||||||
let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
|
|
||||||
// SAFETY: the min() above ensures that step_size is in bounds
|
// SAFETY: the min() above ensures that step_size is in bounds
|
||||||
unsafe {
|
self.ptr = unsafe { self.ptr.add(step_size) };
|
||||||
self.ptr = self.ptr.add(step_size);
|
}
|
||||||
ptr::drop_in_place(to_drop);
|
// SAFETY: the min() above ensures that step_size is in bounds
|
||||||
}
|
unsafe {
|
||||||
|
ptr::drop_in_place(to_drop);
|
||||||
}
|
}
|
||||||
if step_size < n {
|
if step_size < n {
|
||||||
return Err(step_size);
|
return Err(step_size);
|
||||||
@ -237,11 +238,11 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
|||||||
} else {
|
} else {
|
||||||
// SAFETY: same as for advance_by()
|
// SAFETY: same as for advance_by()
|
||||||
self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) };
|
self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) };
|
||||||
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
|
}
|
||||||
// SAFETY: same as for advance_by()
|
let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
|
||||||
unsafe {
|
// SAFETY: same as for advance_by()
|
||||||
ptr::drop_in_place(to_drop);
|
unsafe {
|
||||||
}
|
ptr::drop_in_place(to_drop);
|
||||||
}
|
}
|
||||||
if step_size < n {
|
if step_size < n {
|
||||||
return Err(step_size);
|
return Err(step_size);
|
||||||
|
@ -412,8 +412,9 @@ where
|
|||||||
self.frontiter = None;
|
self.frontiter = None;
|
||||||
|
|
||||||
if let Some(ref mut back) = self.backiter {
|
if let Some(ref mut back) = self.backiter {
|
||||||
if let Err(advanced) = back.advance_by(rem) {
|
match back.advance_by(rem) {
|
||||||
rem -= advanced
|
ret @ Ok(_) => return ret,
|
||||||
|
Err(advanced) => rem -= advanced,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,14 +116,35 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[rustc_inherit_overflow_checks]
|
||||||
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
||||||
if self.n >= n {
|
let mut rem = n;
|
||||||
self.n -= n;
|
|
||||||
return Ok(());
|
let step_one = self.n.saturating_add(rem);
|
||||||
|
match self.iter.advance_by(step_one) {
|
||||||
|
Ok(_) => {
|
||||||
|
rem -= step_one - self.n;
|
||||||
|
self.n = 0;
|
||||||
|
}
|
||||||
|
Err(advanced) => {
|
||||||
|
let advanced_without_skip = advanced.saturating_sub(self.n);
|
||||||
|
self.n = self.n.saturating_sub(advanced);
|
||||||
|
return Err(advanced_without_skip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let rem = n - self.n;
|
|
||||||
self.n = 0;
|
// step_one calculation may have saturated
|
||||||
self.iter.advance_by(rem)
|
if unlikely(rem > 0) {
|
||||||
|
return match self.iter.advance_by(rem) {
|
||||||
|
ret @ Ok(_) => ret,
|
||||||
|
Err(advanced) => {
|
||||||
|
rem -= advanced;
|
||||||
|
Err(n - rem)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user