Skip to content

Commit dc3de6b

Browse files
committed
Convert some iter macros to normal functions
With all the MIR optimization changes that have happened since these were written, let's see if they still actually matter.
1 parent b8dab92 commit dc3de6b

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

core/src/slice/iter/macros.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,19 @@ macro_rules! iterator {
7070
$into_ref:ident,
7171
{$($extra:tt)*}
7272
) => {
73-
// Returns the first element and moves the start of the iterator forwards by 1.
74-
// Greatly improves performance compared to an inlined function. The iterator
75-
// must not be empty.
76-
macro_rules! next_unchecked {
77-
($self: ident) => { $self.post_inc_start(1).$into_ref() }
78-
}
79-
80-
// Returns the last element and moves the end of the iterator backwards by 1.
81-
// Greatly improves performance compared to an inlined function. The iterator
82-
// must not be empty.
83-
macro_rules! next_back_unchecked {
84-
($self: ident) => { $self.pre_dec_end(1).$into_ref() }
85-
}
86-
8773
impl<'a, T> $name<'a, T> {
74+
/// Returns the last element and moves the end of the iterator backwards by 1.
75+
///
76+
/// # Safety
77+
///
78+
/// The iterator must not be empty
79+
#[inline]
80+
unsafe fn next_back_unchecked(&mut self) -> $elem {
81+
// SAFETY: the caller promised it's not empty, so
82+
// the offsetting is in-bounds and there's an element to return.
83+
unsafe { self.pre_dec_end(1).$into_ref() }
84+
}
85+
8886
// Helper function for creating a slice from the iterator.
8987
#[inline(always)]
9088
fn make_slice(&self) -> &'a [T] {
@@ -156,13 +154,13 @@ macro_rules! iterator {
156154
fn next(&mut self) -> Option<$elem> {
157155
// could be implemented with slices, but this avoids bounds checks
158156

159-
// SAFETY: The call to `next_unchecked!` is
157+
// SAFETY: The call to `next_unchecked` is
160158
// safe since we check if the iterator is empty first.
161159
unsafe {
162160
if is_empty!(self) {
163161
None
164162
} else {
165-
Some(next_unchecked!(self))
163+
Some(self.next_unchecked())
166164
}
167165
}
168166
}
@@ -191,7 +189,7 @@ macro_rules! iterator {
191189
// SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
192190
unsafe {
193191
self.post_inc_start(n);
194-
Some(next_unchecked!(self))
192+
Some(self.next_unchecked())
195193
}
196194
}
197195

@@ -392,13 +390,13 @@ macro_rules! iterator {
392390
fn next_back(&mut self) -> Option<$elem> {
393391
// could be implemented with slices, but this avoids bounds checks
394392

395-
// SAFETY: The call to `next_back_unchecked!`
393+
// SAFETY: The call to `next_back_unchecked`
396394
// is safe since we check if the iterator is empty first.
397395
unsafe {
398396
if is_empty!(self) {
399397
None
400398
} else {
401-
Some(next_back_unchecked!(self))
399+
Some(self.next_back_unchecked())
402400
}
403401
}
404402
}
@@ -416,7 +414,7 @@ macro_rules! iterator {
416414
// SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
417415
unsafe {
418416
self.pre_dec_end(n);
419-
Some(next_back_unchecked!(self))
417+
Some(self.next_back_unchecked())
420418
}
421419
}
422420

@@ -436,10 +434,11 @@ macro_rules! iterator {
436434
unsafe impl<T> TrustedLen for $name<'_, T> {}
437435

438436
impl<'a, T> UncheckedIterator for $name<'a, T> {
437+
#[inline]
439438
unsafe fn next_unchecked(&mut self) -> $elem {
440439
// SAFETY: The caller promised there's at least one more item.
441440
unsafe {
442-
next_unchecked!(self)
441+
self.post_inc_start(1).$into_ref()
443442
}
444443
}
445444
}

0 commit comments

Comments
 (0)