Importing rustc-1.53.0 Bug: 194400612 Change-Id: Id2f38eeabc8325fff960e46b89b1cc7216f5227c
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 41a7b13..61d8351 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs
@@ -51,6 +51,9 @@ #[unstable(feature = "trusted_random_access", issue = "none")] pub use self::zip::TrustedRandomAccess; +#[unstable(feature = "iter_zip", issue = "83574")] +pub use self::zip::zip; + /// This trait provides transitive access to source-stage in an interator-adapter pipeline /// under the conditions that /// * the iterator source `S` itself implements `SourceIter<Source = S>` @@ -191,3 +194,26 @@ self.try_fold(init, ok(fold)).unwrap() } } + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl<S: Iterator, I, E> SourceIter for ResultShunt<'_, I, E> +where + I: SourceIter<Source = S>, +{ + type Source = S; + + #[inline] + unsafe fn as_inner(&mut self) -> &mut S { + // SAFETY: unsafe function forwarding to unsafe function with the same requirements + unsafe { SourceIter::as_inner(&mut self.iter) } + } +} + +// SAFETY: ResultShunt::next calls I::find, which has to advance `iter` in order to +// return `Some(_)`. Since `iter` has type `I: InPlaceIterable` it's guaranteed that +// at least one item will be moved out from the underlying source. +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl<I, T, E> InPlaceIterable for ResultShunt<'_, I, E> where + I: Iterator<Item = Result<T, E>> + InPlaceIterable +{ +}
diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 4330144..0d860ae 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs
@@ -1,4 +1,4 @@ -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen}; +use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen}; use crate::ops::Try; /// An iterator with a `peek()` that returns an optional reference to the next @@ -233,7 +233,6 @@ /// Basic usage: /// /// ``` - /// #![feature(peekable_peek_mut)] /// let mut iter = [1, 2, 3].iter().peekable(); /// /// // Like with `peek()`, we can see into the future without advancing the iterator. @@ -251,7 +250,7 @@ /// assert_eq!(iter.collect::<Vec<_>>(), vec![&5, &3]); /// ``` #[inline] - #[unstable(feature = "peekable_peek_mut", issue = "78302")] + #[stable(feature = "peekable_peek_mut", since = "1.53.0")] pub fn peek_mut(&mut self) -> Option<&mut I::Item> { let iter = &mut self.iter; self.peeked.get_or_insert_with(|| iter.next()).as_mut() @@ -334,6 +333,3 @@ unsafe { SourceIter::as_inner(&mut self.iter) } } } - -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index ea7a809..2f8f504 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs
@@ -5,8 +5,8 @@ /// An iterator that iterates two other iterators simultaneously. /// -/// This `struct` is created by [`Iterator::zip`]. See its documentation -/// for more. +/// This `struct` is created by [`zip`] or [`Iterator::zip`]. +/// See their documentation for more. #[derive(Clone)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -33,6 +33,37 @@ } } +/// Converts the arguments to iterators and zips them. +/// +/// See the documentation of [`Iterator::zip`] for more. +/// +/// # Examples +/// +/// ``` +/// #![feature(iter_zip)] +/// use std::iter::zip; +/// +/// let xs = [1, 2, 3]; +/// let ys = [4, 5, 6]; +/// for (x, y) in zip(&xs, &ys) { +/// println!("x:{}, y:{}", x, y); +/// } +/// +/// // Nested zips are also possible: +/// let zs = [7, 8, 9]; +/// for ((x, y), z) in zip(zip(&xs, &ys), &zs) { +/// println!("x:{}, y:{}, z:{}", x, y, z); +/// } +/// ``` +#[unstable(feature = "iter_zip", issue = "83574")] +pub fn zip<A, B>(a: A, b: B) -> Zip<A::IntoIter, B::IntoIter> +where + A: IntoIterator, + B: IntoIterator, +{ + ZipImpl::new(a.into_iter(), b.into_iter()) +} + #[stable(feature = "rust1", since = "1.0.0")] impl<A, B> Iterator for Zip<A, B> where
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index c57ba2b..2a179f0 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs
@@ -389,6 +389,8 @@ DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum, }; +#[unstable(feature = "iter_zip", issue = "83574")] +pub use self::adapters::zip; #[stable(feature = "iter_cloned", since = "1.1.0")] pub use self::adapters::Cloned; #[stable(feature = "iter_copied", since = "1.36.0")]
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index cc80e06..4b293c5 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs
@@ -3,7 +3,7 @@ use crate::mem; use crate::ops::{self, Try}; -use super::{FusedIterator, TrustedLen}; +use super::{FusedIterator, TrustedLen, TrustedRandomAccess}; /// Objects that have a notion of *successor* and *predecessor* operations. /// @@ -493,6 +493,18 @@ )*) } +/// Safety: This macro must only be used on types that are `Copy` and result in ranges +/// which have an exact `size_hint()` where the upper bound must not be `None`. +macro_rules! unsafe_range_trusted_random_access_impl { + ($($t:ty)*) => ($( + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccess for ops::Range<$t> { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + )*) +} + macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( #[stable(feature = "inclusive_range", since = "1.26.0")] @@ -553,6 +565,18 @@ fn max(mut self) -> Option<A> { self.next_back() } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccess, + { + // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for Copy types + // which means even repeated reads of the same index would be safe. + unsafe { Step::forward_unchecked(self.start.clone(), idx) } + } } // These macros generate `ExactSizeIterator` impls for various range types. @@ -574,6 +598,23 @@ u32 i32 } + +unsafe_range_trusted_random_access_impl! { + usize u8 u16 + isize i8 i16 +} + +#[cfg(target_pointer_width = "32")] +unsafe_range_trusted_random_access_impl! { + u32 i32 +} + +#[cfg(target_pointer_width = "64")] +unsafe_range_trusted_random_access_impl! { + u32 i32 + u64 i64 +} + range_incl_exact_iter_impl! { u8 i8
diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 5d4a9fe..919c564 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs
@@ -36,7 +36,7 @@ #[stable(feature = "core_impl_debug", since = "1.9.0")] impl<T> fmt::Debug for Empty<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("Empty") + f.debug_struct("Empty").finish() } }
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 1ae6d15..13a2e24 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs
@@ -198,6 +198,7 @@ /// } /// ``` #[rustc_diagnostic_item = "IntoIterator"] +#[cfg_attr(not(bootstrap), rustc_skip_array_during_method_dispatch)] #[stable(feature = "rust1", since = "1.0.0")] pub trait IntoIterator { /// The type of the elements being iterated over.
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index a07750f..da9e5fd 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs
@@ -81,8 +81,8 @@ ), on( _Self = "[]", - label = "borrow the array with `&` or call `.iter()` on it to iterate over it", - note = "arrays are not iterators, but slices like the following are: `&[1, 2, 3]`" + label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`", + note = "see <https://github.com/rust-lang/rust/pull/65819> for more details" ), on( _Self = "{integral}", @@ -92,7 +92,8 @@ label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )] -#[doc(spotlight)] +#[cfg_attr(bootstrap, doc(spotlight))] +#[cfg_attr(not(bootstrap), doc(notable_trait))] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] pub trait Iterator { @@ -936,20 +937,16 @@ Enumerate::new(self) } - /// Creates an iterator which can use [`peek`] to look at the next element of - /// the iterator without consuming it. + /// Creates an iterator which can use the [`peek`] and [`peek_mut`] methods + /// to look at the next element of the iterator without consuming it. See + /// their documentation for more information. /// - /// Adds a [`peek`] method to an iterator. See its documentation for - /// more information. + /// Note that the underlying iterator is still advanced when [`peek`] or + /// [`peek_mut`] are called for the first time: In order to retrieve the + /// next element, [`next`] is called on the underlying iterator, hence any + /// side effects (i.e. anything other than fetching the next value) of + /// the [`next`] method will occur. /// - /// Note that the underlying iterator is still advanced when [`peek`] is - /// called for the first time: In order to retrieve the next element, - /// [`next`] is called on the underlying iterator, hence any side effects (i.e. - /// anything other than fetching the next value) of the [`next`] method - /// will occur. - /// - /// [`peek`]: Peekable::peek - /// [`next`]: Iterator::next /// /// # Examples /// @@ -976,6 +973,32 @@ /// assert_eq!(iter.peek(), None); /// assert_eq!(iter.next(), None); /// ``` + /// + /// Using [`peek_mut`] to mutate the next item without advancing the + /// iterator: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // `peek_mut()` lets us see into the future + /// assert_eq!(iter.peek_mut(), Some(&mut &1)); + /// assert_eq!(iter.peek_mut(), Some(&mut &1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// if let Some(mut p) = iter.peek_mut() { + /// assert_eq!(*p, &2); + /// // put a value into the iterator + /// *p = &1000; + /// } + /// + /// // The value reappears as the iterator continues + /// assert_eq!(iter.collect::<Vec<_>>(), vec![&1000, &3]); + /// ``` + /// [`peek`]: Peekable::peek + /// [`peek_mut`]: Peekable::peek_mut + /// [`next`]: Iterator::next #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn peekable(self) -> Peekable<Self> @@ -1228,7 +1251,11 @@ /// Creates an iterator that skips the first `n` elements. /// - /// After they have been consumed, the rest of the elements are yielded. + /// `skip(n)` skips elements until `n` elements are skipped or the end of the + /// iterator is reached (whichever happens first). After that, all the remaining + /// elements are yielded. In particular, if the original iterator is too short, + /// then the returned iterator is empty. + /// /// Rather than overriding this method directly, instead override the `nth` method. /// /// # Examples @@ -1252,7 +1279,14 @@ Skip::new(self, n) } - /// Creates an iterator that yields its first `n` elements. + /// Creates an iterator that yields the first `n` elements, or fewer + /// if the underlying iterator ends sooner. + /// + /// `take(n)` yields elements until `n` elements are yielded or the end of + /// the iterator is reached (whichever happens first). + /// The returned iterator is a prefix of length `n` if the original iterator + /// contains at least `n` elements, otherwise it contains all of the + /// (fewer than `n`) elements of the original iterator. /// /// # Examples /// @@ -1461,7 +1495,12 @@ /// [`Some(T)`] again. `fuse()` adapts an iterator, ensuring that after a /// [`None`] is given, it will always return [`None`] forever. /// + /// Note that the [`Fuse`] wrapper is a no-op on iterators that implement + /// the [`FusedIterator`] trait. `fuse()` may therefore behave incorrectly + /// if the [`FusedIterator`] trait is improperly implemented. + /// /// [`Some(T)`]: Some + /// [`FusedIterator`]: crate::iter::FusedIterator /// /// # Examples /// @@ -1612,31 +1651,16 @@ /// Basic usage: /// /// ``` - /// let a = [1, 2, 3]; + /// let mut words = vec!["hello", "world", "of", "Rust"].into_iter(); /// - /// let iter = a.iter(); + /// // Take the first two words. + /// let hello_world: Vec<_> = words.by_ref().take(2).collect(); + /// assert_eq!(hello_world, vec!["hello", "world"]); /// - /// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i); - /// - /// assert_eq!(sum, 6); - /// - /// // if we try to use iter again, it won't work. The following line - /// // gives "error: use of moved value: `iter` - /// // assert_eq!(iter.next(), None); - /// - /// // let's try that again - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// // instead, we add in a .by_ref() - /// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i); - /// - /// assert_eq!(sum, 3); - /// - /// // now this is just fine: - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), None); + /// // Collect the rest of the words. + /// // We can only do this because we used `by_ref` earlier. + /// let of_rust: Vec<_> = words.collect(); + /// assert_eq!(of_rust, vec!["of", "Rust"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self @@ -2109,7 +2133,6 @@ /// ``` /// /// [`reduce()`]: Iterator::reduce - #[doc(alias = "reduce")] #[doc(alias = "inject")] #[inline] #[stable(feature = "rust1", since = "1.0.0")]