Skip to content

Commit 5feb133

Browse files
committed
Add back TrustedRandomAccess-specialization for Vec, but only without coercions
1 parent 32c6a35 commit 5feb133

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

library/alloc/src/vec/into_iter.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::alloc::{Allocator, Global};
22
use crate::raw_vec::RawVec;
33
use core::fmt;
44
use core::intrinsics::arith_offset;
5-
use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen};
5+
use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce};
66
use core::marker::PhantomData;
77
use core::mem::{self};
88
use core::ptr::{self, NonNull};
@@ -162,6 +162,24 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
162162
fn count(self) -> usize {
163163
self.len()
164164
}
165+
166+
#[doc(hidden)]
167+
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
168+
where
169+
Self: TrustedRandomAccessNoCoerce,
170+
{
171+
// SAFETY: the caller must guarantee that `i` is in bounds of the
172+
// `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)`
173+
// is guaranteed to pointer to an element of the `Vec<T>` and
174+
// thus guaranteed to be valid to dereference.
175+
//
176+
// Also note the implementation of `Self: TrustedRandomAccess` requires
177+
// that `T: Copy` so reading elements from the buffer doesn't invalidate
178+
// them for `Drop`.
179+
unsafe {
180+
if mem::size_of::<T>() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) }
181+
}
182+
}
165183
}
166184

167185
#[stable(feature = "rust1", since = "1.0.0")]
@@ -197,6 +215,20 @@ impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
197215
#[unstable(feature = "trusted_len", issue = "37572")]
198216
unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
199217

218+
#[doc(hidden)]
219+
#[unstable(issue = "none", feature = "std_internals")]
220+
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
221+
// and thus we can't implement drop-handling
222+
//
223+
// TrustedRandomAccess (without NoCoerce) must not be implemented because
224+
// subtypes/supertypes of `T` might not be `Copy`
225+
unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A>
226+
where
227+
T: Copy,
228+
{
229+
const MAY_HAVE_SIDE_EFFECT: bool = false;
230+
}
231+
200232
#[cfg(not(no_global_oom_handling))]
201233
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
202234
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {

0 commit comments

Comments
 (0)