Skip to content

Commit 7a5c0c2

Browse files
Auto merge of #147353 - the8472:nondrop-array-iter, r=<try>
only call polymorphic array iter drop machinery when the type requires it
2 parents 2cb4e7d + 7f10971 commit 7a5c0c2

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

library/core/src/array/iter.rs

Lines changed: 12 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,10 @@ 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+
// SAFETY: This is the only place where we drop this field.
328+
unsafe { ManuallyDrop::drop(&mut self.inner) }
329+
}
328330
}
329331
}
330332

0 commit comments

Comments
 (0)