Skip to content

Commit 343b2f6

Browse files
scottmcmgitbot
authored and
gitbot
committed
Simplify slice::Iter::next enough that it inlines
1 parent 058bf21 commit 343b2f6

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

core/src/slice/iter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::iter::{
1111
use crate::marker::PhantomData;
1212
use crate::mem::{self, SizedTypeProperties};
1313
use crate::num::NonZero;
14-
use crate::ptr::{NonNull, without_provenance, without_provenance_mut};
14+
use crate::ptr::{NonNull, null, without_provenance, without_provenance_mut};
1515
use crate::{cmp, fmt};
1616

1717
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]

core/src/slice/iter/macros.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,26 @@ macro_rules! iterator {
154154

155155
#[inline]
156156
fn next(&mut self) -> Option<$elem> {
157-
// could be implemented with slices, but this avoids bounds checks
157+
// intentionally not using the helpers because this is
158+
// one of the most mono'd things in the library.
158159

159-
// SAFETY: The call to `next_unchecked` is
160-
// safe since we check if the iterator is empty first.
160+
let ptr = self.ptr;
161+
let end_or_len = self.end_or_len;
162+
// SAFETY: Type invariants.
161163
unsafe {
162-
if is_empty!(self) {
163-
None
164+
if T::IS_ZST {
165+
let byte_end = end_or_len as *const u8;
166+
if byte_end == null() {
167+
return None;
168+
}
169+
self.end_or_len = byte_end.wrapping_sub(1) as _;
164170
} else {
165-
Some(self.next_unchecked())
171+
if ptr == crate::intrinsics::transmute::<*const T, NonNull<T>>(end_or_len) {
172+
return None;
173+
}
174+
self.ptr = ptr.add(1);
166175
}
176+
crate::intrinsics::transmute::<NonNull<T>, Option<$elem>>(ptr)
167177
}
168178
}
169179

0 commit comments

Comments
 (0)