Skip to content

Commit 3116ce6

Browse files
committed
only call polymorphic array iter drop machinery when the type requires it
1 parent 2cb4e7d commit 3116ce6

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

library/core/src/array/iter.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
33
use crate::intrinsics::transmute_unchecked;
44
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccessNoCoerce};
5-
use crate::mem::MaybeUninit;
5+
use crate::mem::{ManuallyDrop, MaybeUninit};
66
use crate::num::NonZero;
7-
use crate::ops::{IndexRange, Range, Try};
7+
use crate::ops::{Deref as _, DerefMut as _, IndexRange, Range, Try};
88
use crate::{fmt, ptr};
99

1010
mod iter_inner;
@@ -18,17 +18,17 @@ type InnerUnsized<T> = iter_inner::PolymorphicIter<[MaybeUninit<T>]>;
1818
#[rustc_diagnostic_item = "ArrayIntoIter"]
1919
#[derive(Clone)]
2020
pub struct IntoIter<T, const N: usize> {
21-
inner: InnerSized<T, N>,
21+
inner: ManuallyDrop<InnerSized<T, N>>,
2222
}
2323

2424
impl<T, const N: usize> IntoIter<T, N> {
2525
#[inline]
2626
fn unsize(&self) -> &InnerUnsized<T> {
27-
&self.inner
27+
self.inner.deref()
2828
}
2929
#[inline]
3030
fn unsize_mut(&mut self) -> &mut InnerUnsized<T> {
31-
&mut self.inner
31+
self.inner.deref_mut()
3232
}
3333
}
3434

@@ -69,7 +69,7 @@ impl<T, const N: usize> IntoIterator for [T; N] {
6969
// SAFETY: The original array was entirely initialized and the the alive
7070
// range we're passing here represents that fact.
7171
let inner = unsafe { InnerSized::new_unchecked(IndexRange::zero_to(N), data) };
72-
IntoIter { inner }
72+
IntoIter { inner: ManuallyDrop::new(inner) }
7373
}
7474
}
7575

@@ -146,7 +146,7 @@ impl<T, const N: usize> IntoIter<T, N> {
146146
let alive = unsafe { IndexRange::new_unchecked(initialized.start, initialized.end) };
147147
// SAFETY: one of our safety condition is that these items are initialized.
148148
let inner = unsafe { InnerSized::new_unchecked(alive, buffer) };
149-
IntoIter { inner }
149+
IntoIter { inner: ManuallyDrop::new(inner) }
150150
}
151151

152152
/// Creates an iterator over `T` which returns no elements.
@@ -205,7 +205,7 @@ impl<T, const N: usize> IntoIter<T, N> {
205205
#[inline]
206206
pub const fn empty() -> Self {
207207
let inner = InnerSized::empty();
208-
IntoIter { inner }
208+
IntoIter { inner: ManuallyDrop::new(inner) }
209209
}
210210

211211
/// Returns an immutable slice of all elements that have not been yielded
@@ -323,8 +323,9 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
323323
impl<T, const N: usize> Drop for IntoIter<T, N> {
324324
#[inline]
325325
fn drop(&mut self) {
326-
// `inner` now handles this, but it'd technically be a breaking change
327-
// to remove this `impl`, even though it's useless.
326+
if crate::mem::needs_drop::<T>() {
327+
unsafe { ManuallyDrop::drop(&mut self.inner) }
328+
}
328329
}
329330
}
330331

0 commit comments

Comments
 (0)