Skip to content

Commit 236c0cf

Browse files
committed
implement TrustedLen and TrustedRandomAccess for VecDeque iterators
1 parent f826641 commit 236c0cf

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

library/alloc/src/collections/vec_deque/into_iter.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33

44
use super::VecDeque;
55

@@ -36,6 +36,22 @@ impl<T> Iterator for IntoIter<T> {
3636
let len = self.inner.len();
3737
(len, Some(len))
3838
}
39+
40+
#[inline]
41+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
42+
where
43+
Self: TrustedRandomAccess,
44+
{
45+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
46+
// that is in bounds.
47+
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
48+
// multiple repeated reads of the same index would be safe and the
49+
// values are !Drop, thus won't suffer from double drops.
50+
unsafe {
51+
let idx = self.inner.wrap_add(self.inner.tail, idx);
52+
self.inner.buffer_read(idx)
53+
}
54+
}
3955
}
4056

4157
#[stable(feature = "rust1", since = "1.0.0")]
@@ -55,3 +71,17 @@ impl<T> ExactSizeIterator for IntoIter<T> {
5571

5672
#[stable(feature = "fused", since = "1.26.0")]
5773
impl<T> FusedIterator for IntoIter<T> {}
74+
75+
#[unstable(feature = "trusted_len", issue = "37572")]
76+
unsafe impl<T> TrustedLen for IntoIter<T> {}
77+
78+
#[doc(hidden)]
79+
#[unstable(feature = "trusted_random_access", issue = "none")]
80+
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
81+
// and thus we can't implement drop-handling
82+
unsafe impl<T> TrustedRandomAccess for IntoIter<T>
83+
where
84+
T: Copy,
85+
{
86+
const MAY_HAVE_SIDE_EFFECT: bool = false;
87+
}

library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33
use core::ops::Try;
44

55
use super::{count, wrap_index, RingSlices};
@@ -101,6 +101,19 @@ impl<'a, T> Iterator for Iter<'a, T> {
101101
fn last(mut self) -> Option<&'a T> {
102102
self.next_back()
103103
}
104+
105+
#[inline]
106+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
107+
where
108+
Self: TrustedRandomAccess,
109+
{
110+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
111+
// that is in bounds.
112+
unsafe {
113+
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
114+
self.ring.get_unchecked(idx)
115+
}
116+
}
104117
}
105118

106119
#[stable(feature = "rust1", since = "1.0.0")]
@@ -157,3 +170,12 @@ impl<T> ExactSizeIterator for Iter<'_, T> {
157170

158171
#[stable(feature = "fused", since = "1.26.0")]
159172
impl<T> FusedIterator for Iter<'_, T> {}
173+
174+
#[unstable(feature = "trusted_len", issue = "37572")]
175+
unsafe impl<T> TrustedLen for Iter<'_, T> {}
176+
177+
#[doc(hidden)]
178+
#[unstable(feature = "trusted_random_access", issue = "none")]
179+
unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {
180+
const MAY_HAVE_SIDE_EFFECT: bool = false;
181+
}

library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33
use core::marker::PhantomData;
44

55
use super::{count, wrap_index, RingSlices};
@@ -87,6 +87,19 @@ impl<'a, T> Iterator for IterMut<'a, T> {
8787
fn last(mut self) -> Option<&'a mut T> {
8888
self.next_back()
8989
}
90+
91+
#[inline]
92+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
93+
where
94+
Self: TrustedRandomAccess,
95+
{
96+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
97+
// that is in bounds.
98+
unsafe {
99+
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
100+
&mut *self.ring.get_unchecked_mut(idx)
101+
}
102+
}
90103
}
91104

92105
#[stable(feature = "rust1", since = "1.0.0")]
@@ -126,3 +139,12 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {
126139

127140
#[stable(feature = "fused", since = "1.26.0")]
128141
impl<T> FusedIterator for IterMut<'_, T> {}
142+
143+
#[unstable(feature = "trusted_len", issue = "37572")]
144+
unsafe impl<T> TrustedLen for IterMut<'_, T> {}
145+
146+
#[doc(hidden)]
147+
#[unstable(feature = "trusted_random_access", issue = "none")]
148+
unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {
149+
const MAY_HAVE_SIDE_EFFECT: bool = false;
150+
}

0 commit comments

Comments
 (0)