diff options
| author | Frank Steffahn <frank.steffahn@stu.uni-kiel.de> | 2021-07-01 18:56:50 +0200 |
|---|---|---|
| committer | Frank Steffahn <frank.steffahn@stu.uni-kiel.de> | 2021-07-28 14:33:36 +0200 |
| commit | f9c982c8fd4984e1b3751f883291ba52256edc1c (patch) | |
| tree | 534dc4ca66330283f0803c58c30bcd0aaa54eb8a | |
| parent | bbc6b2691ef07401690382103b67509b3189f939 (diff) | |
| download | rust-f9c982c8fd4984e1b3751f883291ba52256edc1c.tar.gz rust-f9c982c8fd4984e1b3751f883291ba52256edc1c.zip | |
Add back TrustedRandomAccess-specialization for Vec, but only without coercions
| -rw-r--r-- | library/alloc/src/vec/into_iter.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 5ea1957200b..89a8330b234 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -2,7 +2,7 @@ use crate::alloc::{Allocator, Global}; use crate::raw_vec::RawVec; use core::fmt; use core::intrinsics::arith_offset; -use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; +use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce}; use core::marker::PhantomData; use core::mem::{self}; use core::ptr::{self, NonNull}; @@ -162,6 +162,24 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> { fn count(self) -> usize { self.len() } + + #[doc(hidden)] + unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item + where + Self: TrustedRandomAccessNoCoerce, + { + // SAFETY: the caller must guarantee that `i` is in bounds of the + // `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)` + // is guaranteed to pointer to an element of the `Vec<T>` and + // thus guaranteed to be valid to dereference. + // + // Also note the implementation of `Self: TrustedRandomAccess` requires + // that `T: Copy` so reading elements from the buffer doesn't invalidate + // them for `Drop`. + unsafe { + if mem::size_of::<T>() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -197,6 +215,20 @@ impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {} +#[doc(hidden)] +#[unstable(issue = "none", feature = "std_internals")] +// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr +// and thus we can't implement drop-handling +// +// TrustedRandomAccess (without NoCoerce) must not be implemented because +// subtypes/supertypes of `T` might not be `Copy` +unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A> +where + T: Copy, +{ + const MAY_HAVE_SIDE_EFFECT: bool = false; +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_into_iter_clone", since = "1.8.0")] impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> { |
