Skip to content

Commit 9c5a27f

Browse files
committed
Don't use mem::zeroed in vec::IntoIter
1 parent 0f806a9 commit 9c5a27f

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

library/alloc/src/vec/into_iter.rs

+26-34
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use core::iter::{
1111
TrustedRandomAccessNoCoerce,
1212
};
1313
use core::marker::PhantomData;
14-
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
14+
use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
1515
use core::num::NonZeroUsize;
1616
#[cfg(not(no_global_oom_handling))]
1717
use core::ops::Deref;
@@ -200,27 +200,23 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
200200

201201
#[inline]
202202
fn next(&mut self) -> Option<T> {
203-
if T::IS_ZST {
204-
if self.ptr.as_ptr() == self.end as *mut _ {
205-
None
206-
} else {
207-
// `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by
208-
// reducing the `end`.
209-
self.end = self.end.wrapping_byte_sub(1);
210-
211-
// Make up a value of this ZST.
212-
Some(unsafe { mem::zeroed() })
203+
let ptr = if T::IS_ZST {
204+
if self.ptr.as_ptr() == self.end as *mut T {
205+
return None;
213206
}
207+
// `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by
208+
// reducing the `end`.
209+
self.end = self.end.wrapping_byte_sub(1);
210+
self.ptr
214211
} else {
215212
if self.ptr == non_null!(self.end, T) {
216-
None
217-
} else {
218-
let old = self.ptr;
219-
self.ptr = unsafe { old.add(1) };
220-
221-
Some(unsafe { ptr::read(old.as_ptr()) })
213+
return None;
222214
}
223-
}
215+
let old = self.ptr;
216+
self.ptr = unsafe { old.add(1) };
217+
old
218+
};
219+
Some(unsafe { ptr.read() })
224220
}
225221

226222
#[inline]
@@ -305,7 +301,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
305301
// Also note the implementation of `Self: TrustedRandomAccess` requires
306302
// that `T: Copy` so reading elements from the buffer doesn't invalidate
307303
// them for `Drop`.
308-
unsafe { if T::IS_ZST { mem::zeroed() } else { self.ptr.add(i).read() } }
304+
unsafe { self.ptr.add(i).read() }
309305
}
310306
}
311307

@@ -314,23 +310,19 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
314310
#[inline]
315311
fn next_back(&mut self) -> Option<T> {
316312
if T::IS_ZST {
317-
if self.end as *mut _ == self.ptr.as_ptr() {
318-
None
319-
} else {
320-
// See above for why 'ptr.offset' isn't used
321-
self.end = self.end.wrapping_byte_sub(1);
322-
323-
// Make up a value of this ZST.
324-
Some(unsafe { mem::zeroed() })
313+
if self.ptr.as_ptr() == self.end as *mut _ {
314+
return None;
325315
}
316+
// See above for why 'ptr.offset' isn't used
317+
self.end = self.end.wrapping_byte_sub(1);
318+
Some(unsafe { ptr::read(self.ptr.as_ptr()) })
326319
} else {
327-
if non_null!(self.end, T) == self.ptr {
328-
None
329-
} else {
330-
let new_end = unsafe { non_null!(self.end, T).sub(1) };
331-
*non_null!(mut self.end, T) = new_end;
332-
333-
Some(unsafe { ptr::read(new_end.as_ptr()) })
320+
if self.ptr == non_null!(self.end, T) {
321+
return None;
322+
}
323+
unsafe {
324+
self.end = self.end.sub(1);
325+
Some(ptr::read(self.end))
334326
}
335327
}
336328
}

tests/codegen/vec-iter.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ pub fn vec_iter_is_empty_nonnull(it: &vec::IntoIter<u8>) -> bool {
3232
it.is_empty()
3333
}
3434

35-
// CHECK-LABEL: @vec_iter_next
35+
// CHECK-LABEL: @vec_iter_next_nonnull
3636
#[no_mangle]
37-
pub fn vec_iter_next(it: &mut vec::IntoIter<u8>) -> Option<u8> {
37+
pub fn vec_iter_next_nonnull(it: &mut vec::IntoIter<u8>) -> Option<u8> {
3838
// CHECK: load ptr
3939
// CHECK-SAME: !nonnull
4040
// CHECK-SAME: !noundef
@@ -44,3 +44,16 @@ pub fn vec_iter_next(it: &mut vec::IntoIter<u8>) -> Option<u8> {
4444
// CHECK: ret
4545
it.next()
4646
}
47+
48+
// CHECK-LABEL: @vec_iter_next_back_nonnull
49+
#[no_mangle]
50+
pub fn vec_iter_next_back_nonnull(it: &mut vec::IntoIter<u8>) -> Option<u8> {
51+
// CHECK: load ptr
52+
// CHECK-SAME: !nonnull
53+
// CHECK-SAME: !noundef
54+
// CHECK: load ptr
55+
// CHECK-SAME: !nonnull
56+
// CHECK-SAME: !noundef
57+
// CHECK: ret
58+
it.next_back()
59+
}

0 commit comments

Comments
 (0)