2
2
3
3
use crate :: intrinsics:: transmute_unchecked;
4
4
use crate :: iter:: { FusedIterator , TrustedLen , TrustedRandomAccessNoCoerce } ;
5
- use crate :: mem:: MaybeUninit ;
5
+ use crate :: mem:: { ManuallyDrop , MaybeUninit } ;
6
6
use crate :: num:: NonZero ;
7
- use crate :: ops:: { IndexRange , Range , Try } ;
7
+ use crate :: ops:: { Deref as _ , DerefMut as _ , IndexRange , Range , Try } ;
8
8
use crate :: { fmt, ptr} ;
9
9
10
10
mod iter_inner;
@@ -18,17 +18,17 @@ type InnerUnsized<T> = iter_inner::PolymorphicIter<[MaybeUninit<T>]>;
18
18
#[ rustc_diagnostic_item = "ArrayIntoIter" ]
19
19
#[ derive( Clone ) ]
20
20
pub struct IntoIter < T , const N : usize > {
21
- inner : InnerSized < T , N > ,
21
+ inner : ManuallyDrop < InnerSized < T , N > > ,
22
22
}
23
23
24
24
impl < T , const N : usize > IntoIter < T , N > {
25
25
#[ inline]
26
26
fn unsize ( & self ) -> & InnerUnsized < T > {
27
- & self . inner
27
+ self . inner . deref ( )
28
28
}
29
29
#[ inline]
30
30
fn unsize_mut ( & mut self ) -> & mut InnerUnsized < T > {
31
- & mut self . inner
31
+ self . inner . deref_mut ( )
32
32
}
33
33
}
34
34
@@ -69,7 +69,7 @@ impl<T, const N: usize> IntoIterator for [T; N] {
69
69
// SAFETY: The original array was entirely initialized and the the alive
70
70
// range we're passing here represents that fact.
71
71
let inner = unsafe { InnerSized :: new_unchecked ( IndexRange :: zero_to ( N ) , data) } ;
72
- IntoIter { inner }
72
+ IntoIter { inner : ManuallyDrop :: new ( inner ) }
73
73
}
74
74
}
75
75
@@ -146,7 +146,7 @@ impl<T, const N: usize> IntoIter<T, N> {
146
146
let alive = unsafe { IndexRange :: new_unchecked ( initialized. start , initialized. end ) } ;
147
147
// SAFETY: one of our safety condition is that these items are initialized.
148
148
let inner = unsafe { InnerSized :: new_unchecked ( alive, buffer) } ;
149
- IntoIter { inner }
149
+ IntoIter { inner : ManuallyDrop :: new ( inner ) }
150
150
}
151
151
152
152
/// Creates an iterator over `T` which returns no elements.
@@ -205,7 +205,7 @@ impl<T, const N: usize> IntoIter<T, N> {
205
205
#[ inline]
206
206
pub const fn empty ( ) -> Self {
207
207
let inner = InnerSized :: empty ( ) ;
208
- IntoIter { inner }
208
+ IntoIter { inner : ManuallyDrop :: new ( inner ) }
209
209
}
210
210
211
211
/// 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> {
323
323
impl < T , const N : usize > Drop for IntoIter < T , N > {
324
324
#[ inline]
325
325
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
+ }
328
330
}
329
331
}
330
332
0 commit comments