From cc39adbfa6073cecf48e83aea8af533b23594fc6 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 27 May 2025 12:00:01 +0800 Subject: [PATCH] implement `TrustedRandomAccessNoCoerce` for `Peekable` --- library/core/src/iter/adapters/peekable.rs | 44 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index a6522659620a0..053f491afa8c9 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -1,5 +1,6 @@ use crate::iter::adapters::SourceIter; -use crate::iter::{FusedIterator, TrustedLen}; +use crate::iter::adapters::zip::try_get_unchecked; +use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccessNoCoerce}; use crate::ops::{ControlFlow, Try}; /// An iterator with a `peek()` that returns an optional reference to the next @@ -115,6 +116,31 @@ impl Iterator for Peekable { }; self.iter.fold(acc, fold) } + + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccessNoCoerce, + { + match &mut self.peeked { + Some(Some(item)) => { + match idx.checked_sub(1) { + // SAFETY: Caller must pass in a valid index. + Some(idx) => unsafe { try_get_unchecked(&mut self.iter, idx) }, + None => { + // SAFETY: we only impl `TrustedRandomAccessNoCoerce` for this type when items are `Copy`. + unsafe { crate::ptr::read(item) } + } + } + } + // `Some(None)` indicates an empty iterator, and it is impossible for the caller + // to pass in any valid index if that is true. + Some(None) => unreachable!(), + None => { + // SAFETY: Caller must pass in a valid index. + unsafe { try_get_unchecked(&mut self.iter, idx) } + } + } + } } #[stable(feature = "double_ended_peek_iterator", since = "1.38.0")] @@ -335,3 +361,19 @@ where unsafe { SourceIter::as_inner(&mut self.iter) } } } + +#[doc(hidden)] +#[unstable(issue = "none", feature = "std_internals")] +#[rustc_unsafe_specialization_marker] +pub trait NonDrop {} + +#[unstable(issue = "none", feature = "std_internals")] +impl NonDrop for T {} + +#[unstable(feature = "trusted_random_access", issue = "none")] +unsafe impl TrustedRandomAccessNoCoerce for Peekable +where + I::Item: NonDrop, +{ + const MAY_HAVE_SIDE_EFFECT: bool = false; +}