Skip to content

Commit cc39adb

Browse files
committed
implement TrustedRandomAccessNoCoerce for Peekable
1 parent 46264e6 commit cc39adb

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

library/core/src/iter/adapters/peekable.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::iter::adapters::SourceIter;
2-
use crate::iter::{FusedIterator, TrustedLen};
2+
use crate::iter::adapters::zip::try_get_unchecked;
3+
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccessNoCoerce};
34
use crate::ops::{ControlFlow, Try};
45

56
/// An iterator with a `peek()` that returns an optional reference to the next
@@ -115,6 +116,31 @@ impl<I: Iterator> Iterator for Peekable<I> {
115116
};
116117
self.iter.fold(acc, fold)
117118
}
119+
120+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
121+
where
122+
Self: TrustedRandomAccessNoCoerce,
123+
{
124+
match &mut self.peeked {
125+
Some(Some(item)) => {
126+
match idx.checked_sub(1) {
127+
// SAFETY: Caller must pass in a valid index.
128+
Some(idx) => unsafe { try_get_unchecked(&mut self.iter, idx) },
129+
None => {
130+
// SAFETY: we only impl `TrustedRandomAccessNoCoerce` for this type when items are `Copy`.
131+
unsafe { crate::ptr::read(item) }
132+
}
133+
}
134+
}
135+
// `Some(None)` indicates an empty iterator, and it is impossible for the caller
136+
// to pass in any valid index if that is true.
137+
Some(None) => unreachable!(),
138+
None => {
139+
// SAFETY: Caller must pass in a valid index.
140+
unsafe { try_get_unchecked(&mut self.iter, idx) }
141+
}
142+
}
143+
}
118144
}
119145

120146
#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
@@ -335,3 +361,19 @@ where
335361
unsafe { SourceIter::as_inner(&mut self.iter) }
336362
}
337363
}
364+
365+
#[doc(hidden)]
366+
#[unstable(issue = "none", feature = "std_internals")]
367+
#[rustc_unsafe_specialization_marker]
368+
pub trait NonDrop {}
369+
370+
#[unstable(issue = "none", feature = "std_internals")]
371+
impl<T: Copy> NonDrop for T {}
372+
373+
#[unstable(feature = "trusted_random_access", issue = "none")]
374+
unsafe impl<I: Iterator + TrustedRandomAccessNoCoerce> TrustedRandomAccessNoCoerce for Peekable<I>
375+
where
376+
I::Item: NonDrop,
377+
{
378+
const MAY_HAVE_SIDE_EFFECT: bool = false;
379+
}

0 commit comments

Comments
 (0)