about summary refs log tree commit diff
path: root/library/core/src/array
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-03-22 02:20:26 +0100
committerGitHub <noreply@github.com>2021-03-22 02:20:26 +0100
commit29a53e6e69d5684a598770652e9c170dd4d149d8 (patch)
treef46e66ca5ddba746cb4e833120960ac68bb8417a /library/core/src/array
parentad8aa185dff457cc18dc38c80d31d348af3d3486 (diff)
parent08a1dd287d371b8df7fbef610e66bc925b3eea0b (diff)
downloadrust-29a53e6e69d5684a598770652e9c170dd4d149d8.tar.gz
rust-29a53e6e69d5684a598770652e9c170dd4d149d8.zip
Rollup merge of #81607 - the8472:trustedrandomaccess-all-the-things, r=m-ou-se
Implement TrustedLen and TrustedRandomAccess for Range<integer>, array::IntoIter, VecDequeue's iterators

This should make some `FromIterator` and `.zip()` specializations applicable in a few more cases.

``@rustbot`` label libs-impl
Diffstat (limited to 'library/core/src/array')
-rw-r--r--library/core/src/array/iter.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 4472fba26b9..f82454addd0 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     fmt,
-    iter::{ExactSizeIterator, FusedIterator, TrustedLen},
+    iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
     mem::{self, MaybeUninit},
     ops::Range,
     ptr,
@@ -130,6 +130,18 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
     fn last(mut self) -> Option<Self::Item> {
         self.next_back()
     }
+
+    #[inline]
+    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
+    where
+        Self: TrustedRandomAccess,
+    {
+        // SAFETY: Callers are only allowed to pass an index that is in bounds
+        // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
+        // multiple repeated reads of the same index would be safe and the
+        // values aree !Drop, thus won't suffer from double drops.
+        unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
+    }
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
@@ -184,6 +196,17 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
 unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}
 
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
+// and thus we can't implement drop-handling
+unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
+where
+    T: Copy,
+{
+    const MAY_HAVE_SIDE_EFFECT: bool = false;
+}
+
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
 impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
     fn clone(&self) -> Self {