/// ```rust
/// #![feature(box_syntax)]
/// fn main() {
- /// let a = (box [1,2,3]).len();
+ /// let a = (box [1, 2, 3]).len();
/// }
/// ```
///
///
/// impl<T: ?Sized> MyIterator for T where T: Iterator { }
///
- /// let x = vec![1,2,3];
+ /// let x = vec![1, 2, 3];
/// let _ = x.iter().is_sorted();
/// ```
///
//! - ui/or-patterns
//! - ui/consts/const_in_pattern
//! - ui/rfc-2008-non-exhaustive
+//! - ui/half-open-range-patterns
//! - probably many others
//! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
//! reason not to, for example if they depend on a particular feature like or_patterns.
FatalError.raise()
}
- /// Note: It was decided to not add a test case, because it would be to big.
+ /// Note: It was decided to not add a test case, because it would be too big.
/// <https://github.com/rust-lang/rust/pull/50296#issuecomment-392135180>
fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! {
self.fatal_span_(
/// let mut count: BTreeMap<&str, usize> = BTreeMap::new();
///
/// // count the number of occurrences of letters in the vec
- /// for x in vec!["a","b","a","c","a","b"] {
+ /// for x in vec!["a", "b", "a", "c", "a", "b"] {
/// *count.entry(x).or_insert(0) += 1;
/// }
///
use crate::rc::Rc;
use crate::string::{String, ToString};
use crate::vec::Vec;
+use std::cmp::Ordering;
use std::convert::TryFrom;
use std::iter::{self, FromIterator};
use std::mem;
use std::ops::Bound::{self, Excluded, Included, Unbounded};
use std::ops::RangeBounds;
use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
mod ord_chaos;
use ord_chaos::{Cyclic3, Governed, Governor};
struct D;
impl Drop for D {
fn drop(&mut self) {
- if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
+ if DROPS.fetch_add(1, SeqCst) == 1 {
panic!("panic in `drop`");
}
}
catch_unwind(move || {
drop(map.drain_filter(|i, _| {
- PREDS.fetch_add(1usize << i, Ordering::SeqCst);
+ PREDS.fetch_add(1usize << i, SeqCst);
true
}))
})
.unwrap_err();
- assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
- assert_eq!(DROPS.load(Ordering::SeqCst), 3);
+ assert_eq!(PREDS.load(SeqCst), 0x011);
+ assert_eq!(DROPS.load(SeqCst), 3);
}
#[test]
struct D;
impl Drop for D {
fn drop(&mut self) {
- DROPS.fetch_add(1, Ordering::SeqCst);
+ DROPS.fetch_add(1, SeqCst);
}
}
catch_unwind(AssertUnwindSafe(|| {
drop(map.drain_filter(|i, _| {
- PREDS.fetch_add(1usize << i, Ordering::SeqCst);
+ PREDS.fetch_add(1usize << i, SeqCst);
match i {
0 => true,
_ => panic!(),
}))
.unwrap_err();
- assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
- assert_eq!(DROPS.load(Ordering::SeqCst), 1);
+ assert_eq!(PREDS.load(SeqCst), 0x011);
+ assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(map.len(), 2);
assert_eq!(map.first_entry().unwrap().key(), &4);
assert_eq!(map.last_entry().unwrap().key(), &8);
struct D;
impl Drop for D {
fn drop(&mut self) {
- DROPS.fetch_add(1, Ordering::SeqCst);
+ DROPS.fetch_add(1, SeqCst);
}
}
{
let mut it = map.drain_filter(|i, _| {
- PREDS.fetch_add(1usize << i, Ordering::SeqCst);
+ PREDS.fetch_add(1usize << i, SeqCst);
match i {
0 => true,
_ => panic!(),
assert!(matches!(result, Ok(None)));
}
- assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
- assert_eq!(DROPS.load(Ordering::SeqCst), 1);
+ assert_eq!(PREDS.load(SeqCst), 0x011);
+ assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(map.len(), 2);
assert_eq!(map.first_entry().unwrap().key(), &4);
assert_eq!(map.last_entry().unwrap().key(), &8);
// undefined.
#[test]
fn test_bad_zst() {
- use std::cmp::Ordering;
-
#[derive(Clone, Copy, Debug)]
struct Bad;
impl Drop for D {
fn drop(&mut self) {
- if DROPS.fetch_add(1, Ordering::SeqCst) == 0 {
+ if DROPS.fetch_add(1, SeqCst) == 0 {
panic!("panic in `drop`");
}
}
catch_unwind(move || left.append(&mut right)).unwrap_err();
- assert_eq!(DROPS.load(Ordering::SeqCst), 4); // Rust issue #47949 ate one little piggy
+ assert_eq!(DROPS.load(SeqCst), 4); // Rust issue #47949 ate one little piggy
}
#[test]
impl Drop for D {
fn drop(&mut self) {
- if DROPS.fetch_add(1, Ordering::SeqCst) == 3 {
+ if DROPS.fetch_add(1, SeqCst) == 3 {
panic!("panic in `drop`");
}
}
catch_unwind(move || drop(map.into_iter())).unwrap_err();
- assert_eq!(DROPS.load(Ordering::SeqCst), 5);
+ assert_eq!(DROPS.load(SeqCst), 5);
}
#[test]
struct D;
impl Drop for D {
fn drop(&mut self) {
- if DROPS.fetch_add(1, Ordering::SeqCst) == PANIC_POINT.load(Ordering::SeqCst) {
+ if DROPS.fetch_add(1, SeqCst) == PANIC_POINT.load(SeqCst) {
panic!("panic in `drop`");
}
}
}
for panic_point in vec![0, 1, size - 2, size - 1] {
- DROPS.store(0, Ordering::SeqCst);
- PANIC_POINT.store(panic_point, Ordering::SeqCst);
+ DROPS.store(0, SeqCst);
+ PANIC_POINT.store(panic_point, SeqCst);
let map: BTreeMap<_, _> = (0..size).map(|i| (i, D)).collect();
catch_unwind(move || drop(map.into_iter())).unwrap_err();
- assert_eq!(DROPS.load(Ordering::SeqCst), size);
+ assert_eq!(DROPS.load(SeqCst), size);
}
}
{
match search_linear(&node, key) {
(idx, true) => Found(unsafe { Handle::new_kv(node, idx) }),
- (idx, false) => SearchResult::GoDown(unsafe { Handle::new_edge(node, idx) }),
+ (idx, false) => GoDown(unsafe { Handle::new_edge(node, idx) }),
}
}
use super::super::DeterministicRng;
use super::*;
use crate::vec::Vec;
+use std::cmp::Ordering;
use std::iter::FromIterator;
use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::sync::atomic::{AtomicU32, Ordering};
+use std::sync::atomic::{AtomicU32, Ordering::SeqCst};
#[test]
fn test_clone_eq() {
struct D(i32);
impl Drop for D {
fn drop(&mut self) {
- if DROPS.fetch_add(1, Ordering::SeqCst) == 1 {
+ if DROPS.fetch_add(1, SeqCst) == 1 {
panic!("panic in `drop`");
}
}
catch_unwind(move || {
drop(set.drain_filter(|d| {
- PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
+ PREDS.fetch_add(1u32 << d.0, SeqCst);
true
}))
})
.ok();
- assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
- assert_eq!(DROPS.load(Ordering::SeqCst), 3);
+ assert_eq!(PREDS.load(SeqCst), 0x011);
+ assert_eq!(DROPS.load(SeqCst), 3);
}
#[test]
struct D(i32);
impl Drop for D {
fn drop(&mut self) {
- DROPS.fetch_add(1, Ordering::SeqCst);
+ DROPS.fetch_add(1, SeqCst);
}
}
catch_unwind(AssertUnwindSafe(|| {
drop(set.drain_filter(|d| {
- PREDS.fetch_add(1u32 << d.0, Ordering::SeqCst);
+ PREDS.fetch_add(1u32 << d.0, SeqCst);
match d.0 {
0 => true,
_ => panic!(),
}))
.ok();
- assert_eq!(PREDS.load(Ordering::SeqCst), 0x011);
- assert_eq!(DROPS.load(Ordering::SeqCst), 1);
+ assert_eq!(PREDS.load(SeqCst), 0x011);
+ assert_eq!(DROPS.load(SeqCst), 1);
assert_eq!(set.len(), 2);
assert_eq!(set.first().unwrap().0, 4);
assert_eq!(set.last().unwrap().0, 8);
#[test]
fn test_recovery() {
- use std::cmp::Ordering;
-
#[derive(Debug)]
struct Foo(&'static str, i32);
/// ```
/// use std::collections::VecDeque;
///
- /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
+ /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
/// let buf2 = buf.split_off(1);
/// assert_eq!(buf, [1]);
/// assert_eq!(buf2, [2, 3]);
/// (3, 1), (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
/// (1, 21), (2, 34), (4, 55)].into();
///
- /// assert_eq!(deque.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
- /// assert_eq!(deque.binary_search_by_key(&4, |&(a,b)| b), Err(7));
- /// assert_eq!(deque.binary_search_by_key(&100, |&(a,b)| b), Err(13));
- /// let r = deque.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert_eq!(deque.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+ /// assert_eq!(deque.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+ /// assert_eq!(deque.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+ /// let r = deque.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(matches!(r, Ok(1..=4)));
/// ```
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
/// }
/// x.set_len(size);
/// }
- /// assert_eq!(&*x, &[0,1,2,3]);
+ /// assert_eq!(&*x, &[0, 1, 2, 3]);
/// ```
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
#[inline]
/// # Examples
///
/// ```
- /// let mut vec = vec![1,2,3];
+ /// let mut vec = vec![1, 2, 3];
/// let vec2 = vec.split_off(1);
/// assert_eq!(vec, [1]);
/// assert_eq!(vec2, [2, 3]);
/// must not overflow (i.e., the rounded value must be less than
/// or equal to `usize::MAX`).
#[stable(feature = "alloc_layout", since = "1.28.0")]
- #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+ #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
if !align.is_power_of_two() {
/// The minimum size in bytes for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
- #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+ #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn size(&self) -> usize {
self.size_
/// The minimum byte alignment for a memory block of this layout.
#[stable(feature = "alloc_layout", since = "1.28.0")]
- #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+ #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
#[inline]
pub const fn align(&self) -> usize {
self.align_.get()
/// # Examples
///
/// ```
- /// #![feature(refcell_take)]
/// use std::cell::RefCell;
///
/// let c = RefCell::new(5);
/// assert_eq!(five, 5);
/// assert_eq!(c.into_inner(), 0);
/// ```
- #[unstable(feature = "refcell_take", issue = "71395")]
+ #[stable(feature = "refcell_take", since = "1.50.0")]
pub fn take(&self) -> T {
self.replace(Default::default())
}
/// # Examples
///
/// ```
- /// #![feature(clamp)]
- ///
/// assert!((-3).clamp(-2, 1) == -2);
/// assert!(0.clamp(-2, 1) == 0);
/// assert!(2.clamp(-2, 1) == 1);
/// ```
#[must_use]
- #[unstable(feature = "clamp", issue = "44095")]
+ #[stable(feature = "clamp", since = "1.50.0")]
fn clamp(self, min: Self, max: Self) -> Self
where
Self: Sized,
use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
-use crate::ops::Try;
-use crate::usize;
+use crate::{ops::Try, usize};
/// An iterator that links two iterators together, in a chain.
///
--- /dev/null
+use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::ops::Try;
+
+/// An iterator that clones the elements of an underlying iterator.
+///
+/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`cloned`]: Iterator::cloned
+/// [`Iterator`]: trait.Iterator.html
+#[stable(feature = "iter_cloned", since = "1.1.0")]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct Cloned<I> {
+ it: I,
+}
+
+impl<I> Cloned<I> {
+ pub(in crate::iter) fn new(it: I) -> Cloned<I> {
+ Cloned { it }
+ }
+}
+
+fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
+ move |acc, elt| f(acc, elt.clone())
+}
+
+#[stable(feature = "iter_cloned", since = "1.1.0")]
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Clone,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ self.it.next().cloned()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.it.size_hint()
+ }
+
+ fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.it.try_fold(init, clone_try_fold(f))
+ }
+
+ fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.it.map(T::clone).fold(init, f)
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
+ where
+ Self: TrustedRandomAccess,
+ {
+ // SAFETY: the caller must uphold the contract for
+ // `Iterator::__iterator_get_unchecked`.
+ unsafe { try_get_unchecked(&mut self.it, idx).clone() }
+ }
+}
+
+#[stable(feature = "iter_cloned", since = "1.1.0")]
+impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
+where
+ I: DoubleEndedIterator<Item = &'a T>,
+ T: Clone,
+{
+ fn next_back(&mut self) -> Option<T> {
+ self.it.next_back().cloned()
+ }
+
+ fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.it.try_rfold(init, clone_try_fold(f))
+ }
+
+ fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.it.map(T::clone).rfold(init, f)
+ }
+}
+
+#[stable(feature = "iter_cloned", since = "1.1.0")]
+impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
+where
+ I: ExactSizeIterator<Item = &'a T>,
+ T: Clone,
+{
+ fn len(&self) -> usize {
+ self.it.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.it.is_empty()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<'a, I, T: 'a> FusedIterator for Cloned<I>
+where
+ I: FusedIterator<Item = &'a T>,
+ T: Clone,
+{
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccess for Cloned<I>
+where
+ I: TrustedRandomAccess,
+{
+ #[inline]
+ fn may_have_side_effect() -> bool {
+ true
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
+where
+ I: TrustedLen<Item = &'a T>,
+ T: Clone,
+{
+}
--- /dev/null
+use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::ops::Try;
+
+/// An iterator that copies the elements of an underlying iterator.
+///
+/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`copied`]: Iterator::copied
+/// [`Iterator`]: trait.Iterator.html
+#[stable(feature = "iter_copied", since = "1.36.0")]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct Copied<I> {
+ it: I,
+}
+
+impl<I> Copied<I> {
+ pub(in crate::iter) fn new(it: I) -> Copied<I> {
+ Copied { it }
+ }
+}
+
+fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
+ move |acc, &elt| f(acc, elt)
+}
+
+fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
+ move |acc, &elt| f(acc, elt)
+}
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+impl<'a, I, T: 'a> Iterator for Copied<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Copy,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ self.it.next().copied()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.it.size_hint()
+ }
+
+ fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.it.try_fold(init, copy_try_fold(f))
+ }
+
+ fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.it.fold(init, copy_fold(f))
+ }
+
+ fn nth(&mut self, n: usize) -> Option<T> {
+ self.it.nth(n).copied()
+ }
+
+ fn last(self) -> Option<T> {
+ self.it.last().copied()
+ }
+
+ fn count(self) -> usize {
+ self.it.count()
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
+ where
+ Self: TrustedRandomAccess,
+ {
+ // SAFETY: the caller must uphold the contract for
+ // `Iterator::__iterator_get_unchecked`.
+ *unsafe { try_get_unchecked(&mut self.it, idx) }
+ }
+}
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
+where
+ I: DoubleEndedIterator<Item = &'a T>,
+ T: Copy,
+{
+ fn next_back(&mut self) -> Option<T> {
+ self.it.next_back().copied()
+ }
+
+ fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.it.try_rfold(init, copy_try_fold(f))
+ }
+
+ fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.it.rfold(init, copy_fold(f))
+ }
+}
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
+where
+ I: ExactSizeIterator<Item = &'a T>,
+ T: Copy,
+{
+ fn len(&self) -> usize {
+ self.it.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.it.is_empty()
+ }
+}
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+impl<'a, I, T: 'a> FusedIterator for Copied<I>
+where
+ I: FusedIterator<Item = &'a T>,
+ T: Copy,
+{
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccess for Copied<I>
+where
+ I: TrustedRandomAccess,
+{
+ #[inline]
+ fn may_have_side_effect() -> bool {
+ I::may_have_side_effect()
+ }
+}
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
+where
+ I: TrustedLen<Item = &'a T>,
+ T: Copy,
+{
+}
--- /dev/null
+use crate::{iter::FusedIterator, ops::Try};
+
+/// An iterator that repeats endlessly.
+///
+/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`cycle`]: Iterator::cycle
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Cycle<I> {
+ orig: I,
+ iter: I,
+}
+
+impl<I: Clone> Cycle<I> {
+ pub(in crate::iter) fn new(iter: I) -> Cycle<I> {
+ Cycle { orig: iter.clone(), iter }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> Iterator for Cycle<I>
+where
+ I: Clone + Iterator,
+{
+ type Item = <I as Iterator>::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<<I as Iterator>::Item> {
+ match self.iter.next() {
+ None => {
+ self.iter = self.orig.clone();
+ self.iter.next()
+ }
+ y => y,
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // the cycle iterator is either empty or infinite
+ match self.orig.size_hint() {
+ sz @ (0, Some(0)) => sz,
+ (0, _) => (0, None),
+ _ => (usize::MAX, None),
+ }
+ }
+
+ #[inline]
+ fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+ where
+ F: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ // fully iterate the current iterator. this is necessary because
+ // `self.iter` may be empty even when `self.orig` isn't
+ acc = self.iter.try_fold(acc, &mut f)?;
+ self.iter = self.orig.clone();
+
+ // complete a full cycle, keeping track of whether the cycled
+ // iterator is empty or not. we need to return early in case
+ // of an empty iterator to prevent an infinite loop
+ let mut is_empty = true;
+ acc = self.iter.try_fold(acc, |acc, x| {
+ is_empty = false;
+ f(acc, x)
+ })?;
+
+ if is_empty {
+ return try { acc };
+ }
+
+ loop {
+ self.iter = self.orig.clone();
+ acc = self.iter.try_fold(acc, &mut f)?;
+ }
+ }
+
+ // No `fold` override, because `fold` doesn't make much sense for `Cycle`,
+ // and we can't do anything better than the default.
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
--- /dev/null
+use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
+use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
+use crate::ops::{Add, AddAssign, Try};
+
+/// An iterator that yields the current count and the element during iteration.
+///
+/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`enumerate`]: Iterator::enumerate
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Enumerate<I> {
+ iter: I,
+ count: usize,
+}
+impl<I> Enumerate<I> {
+ pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
+ Enumerate { iter, count: 0 }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> Iterator for Enumerate<I>
+where
+ I: Iterator,
+{
+ type Item = (usize, <I as Iterator>::Item);
+
+ /// # Overflow Behavior
+ ///
+ /// The method does no guarding against overflows, so enumerating more than
+ /// `usize::MAX` elements either produces the wrong result or panics. If
+ /// debug assertions are enabled, a panic is guaranteed.
+ ///
+ /// # Panics
+ ///
+ /// Might panic if the index of the element overflows a `usize`.
+ #[inline]
+ fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
+ let a = self.iter.next()?;
+ let i = self.count;
+ // Possible undefined overflow.
+ AddAssign::add_assign(&mut self.count, 1);
+ Some((i, a))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
+ let a = self.iter.nth(n)?;
+ // Possible undefined overflow.
+ let i = Add::add(self.count, n);
+ self.count = Add::add(i, 1);
+ Some((i, a))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count()
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ #[inline]
+ fn enumerate<'a, T, Acc, R>(
+ count: &'a mut usize,
+ mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
+ ) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, item| {
+ let acc = fold(acc, (*count, item));
+ // Possible undefined overflow.
+ AddAssign::add_assign(count, 1);
+ acc
+ }
+ }
+
+ self.iter.try_fold(init, enumerate(&mut self.count, fold))
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn enumerate<T, Acc>(
+ mut count: usize,
+ mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
+ ) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, item| {
+ let acc = fold(acc, (count, item));
+ // Possible undefined overflow.
+ AddAssign::add_assign(&mut count, 1);
+ acc
+ }
+ }
+
+ self.iter.fold(init, enumerate(self.count, fold))
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
+ where
+ Self: TrustedRandomAccess,
+ {
+ // SAFETY: the caller must uphold the contract for
+ // `Iterator::__iterator_get_unchecked`.
+ let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
+ (Add::add(self.count, idx), value)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> DoubleEndedIterator for Enumerate<I>
+where
+ I: ExactSizeIterator + DoubleEndedIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
+ let a = self.iter.next_back()?;
+ let len = self.iter.len();
+ // Can safely add, `ExactSizeIterator` promises that the number of
+ // elements fits into a `usize`.
+ Some((self.count + len, a))
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
+ let a = self.iter.nth_back(n)?;
+ let len = self.iter.len();
+ // Can safely add, `ExactSizeIterator` promises that the number of
+ // elements fits into a `usize`.
+ Some((self.count + len, a))
+ }
+
+ #[inline]
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ // Can safely add and subtract the count, as `ExactSizeIterator` promises
+ // that the number of elements fits into a `usize`.
+ fn enumerate<T, Acc, R>(
+ mut count: usize,
+ mut fold: impl FnMut(Acc, (usize, T)) -> R,
+ ) -> impl FnMut(Acc, T) -> R {
+ move |acc, item| {
+ count -= 1;
+ fold(acc, (count, item))
+ }
+ }
+
+ let count = self.count + self.iter.len();
+ self.iter.try_rfold(init, enumerate(count, fold))
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ // Can safely add and subtract the count, as `ExactSizeIterator` promises
+ // that the number of elements fits into a `usize`.
+ fn enumerate<T, Acc>(
+ mut count: usize,
+ mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
+ ) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, item| {
+ count -= 1;
+ fold(acc, (count, item))
+ }
+ }
+
+ let count = self.count + self.iter.len();
+ self.iter.rfold(init, enumerate(count, fold))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ExactSizeIterator for Enumerate<I>
+where
+ I: ExactSizeIterator,
+{
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccess for Enumerate<I>
+where
+ I: TrustedRandomAccess,
+{
+ fn may_have_side_effect() -> bool {
+ I::may_have_side_effect()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
+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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::Try;
+
+/// An iterator that filters the elements of `iter` with `predicate`.
+///
+/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`filter`]: Iterator::filter
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct Filter<I, P> {
+ iter: I,
+ predicate: P,
+}
+impl<I, P> Filter<I, P> {
+ pub(in crate::iter) fn new(iter: I, predicate: P) -> Filter<I, P> {
+ Filter { iter, predicate }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Filter").field("iter", &self.iter).finish()
+ }
+}
+
+fn filter_fold<T, Acc>(
+ mut predicate: impl FnMut(&T) -> bool,
+ mut fold: impl FnMut(Acc, T) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
+}
+
+fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
+ predicate: &'a mut impl FnMut(&T) -> bool,
+ mut fold: impl FnMut(Acc, T) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, item| if predicate(&item) { fold(acc, item) } else { try { acc } }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator, P> Iterator for Filter<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ self.iter.find(&mut self.predicate)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the predicate
+ }
+
+ // this special case allows the compiler to make `.filter(_).count()`
+ // branchless. Barring perfect branch prediction (which is unattainable in
+ // the general case), this will be much faster in >90% of cases (containing
+ // virtually all real workloads) and only a tiny bit slower in the rest.
+ //
+ // Having this specialization thus allows us to write `.filter(p).count()`
+ // where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is
+ // less readable and also less backwards-compatible to Rust before 1.10.
+ //
+ // Using the branchless version will also simplify the LLVM byte code, thus
+ // leaving more budget for LLVM optimizations.
+ #[inline]
+ fn count(self) -> usize {
+ #[inline]
+ fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
+ move |x| predicate(&x) as usize
+ }
+
+ self.iter.map(to_usize(self.predicate)).sum()
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(init, filter_fold(self.predicate, fold))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<I::Item> {
+ self.iter.rfind(&mut self.predicate)
+ }
+
+ #[inline]
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.rfold(init, filter_fold(self.predicate, fold))
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator that uses `f` to both filter and map elements from `iter`.
+///
+/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`filter_map`]: Iterator::filter_map
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct FilterMap<I, F> {
+ iter: I,
+ f: F,
+}
+impl<I, F> FilterMap<I, F> {
+ pub(in crate::iter) fn new(iter: I, f: F) -> FilterMap<I, F> {
+ FilterMap { iter, f }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("FilterMap").field("iter", &self.iter).finish()
+ }
+}
+
+fn filter_map_fold<T, B, Acc>(
+ mut f: impl FnMut(T) -> Option<B>,
+ mut fold: impl FnMut(Acc, B) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, item| match f(item) {
+ Some(x) => fold(acc, x),
+ None => acc,
+ }
+}
+
+fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
+ f: &'a mut impl FnMut(T) -> Option<B>,
+ mut fold: impl FnMut(Acc, B) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, item| match f(item) {
+ Some(x) => fold(acc, x),
+ None => try { acc },
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
+where
+ F: FnMut(I::Item) -> Option<B>,
+{
+ type Item = B;
+
+ #[inline]
+ fn next(&mut self) -> Option<B> {
+ self.iter.find_map(&mut self.f)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the predicate
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(init, filter_map_fold(self.f, fold))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
+where
+ F: FnMut(I::Item) -> Option<B>,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<B> {
+ #[inline]
+ fn find<T, B>(
+ f: &mut impl FnMut(T) -> Option<B>,
+ ) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
+ move |(), x| match f(x) {
+ Some(x) => ControlFlow::Break(x),
+ None => ControlFlow::CONTINUE,
+ }
+ }
+
+ self.iter.try_rfold((), find(&mut self.f)).break_value()
+ }
+
+ #[inline]
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.rfold(init, filter_map_fold(self.f, fold))
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F>
+where
+ F: FnMut(I::Item) -> Option<B>,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where
+ F: FnMut(I::Item) -> Option<B>
+{
+}
use crate::fmt;
+use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
use crate::ops::Try;
-use super::super::{DoubleEndedIterator, Fuse, FusedIterator, Iterator};
-use super::Map;
-
/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
pub struct FlatMap<I, U: IntoIterator, F> {
inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
}
+
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
- pub(in super::super) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
+ pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
FlatMap { inner: FlattenCompat::new(iter.map(f)) }
}
}
-use super::InPlaceIterable;
use crate::intrinsics;
-use crate::iter::adapters::zip::try_get_unchecked;
-use crate::iter::adapters::SourceIter;
-use crate::iter::TrustedRandomAccess;
-use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
+use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter};
+use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedRandomAccess};
use crate::ops::Try;
/// An iterator that yields `None` forever after the underlying iterator
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::Try;
+
+/// An iterator that calls a function with a reference to each element before
+/// yielding it.
+///
+/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`inspect`]: Iterator::inspect
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct Inspect<I, F> {
+ iter: I,
+ f: F,
+}
+impl<I, F> Inspect<I, F> {
+ pub(in crate::iter) fn new(iter: I, f: F) -> Inspect<I, F> {
+ Inspect { iter, f }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Inspect").field("iter", &self.iter).finish()
+ }
+}
+
+impl<I: Iterator, F> Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+{
+ #[inline]
+ fn do_inspect(&mut self, elt: Option<I::Item>) -> Option<I::Item> {
+ if let Some(ref a) = elt {
+ (self.f)(a);
+ }
+
+ elt
+ }
+}
+
+fn inspect_fold<T, Acc>(
+ mut f: impl FnMut(&T),
+ mut fold: impl FnMut(Acc, T) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, item| {
+ f(&item);
+ fold(acc, item)
+ }
+}
+
+fn inspect_try_fold<'a, T, Acc, R>(
+ f: &'a mut impl FnMut(&T),
+ mut fold: impl FnMut(Acc, T) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, item| {
+ f(&item);
+ fold(acc, item)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator, F> Iterator for Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ let next = self.iter.next();
+ self.do_inspect(next)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_fold(init, inspect_try_fold(&mut self.f, fold))
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(init, inspect_fold(self.f, fold))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<I::Item> {
+ let next = self.iter.next_back();
+ self.do_inspect(next)
+ }
+
+ #[inline]
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_rfold(init, inspect_try_fold(&mut self.f, fold))
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.rfold(init, inspect_fold(self.f, fold))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+{
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F>
+where
+ F: FnMut(&I::Item),
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}
--- /dev/null
+use crate::fmt;
+use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
+use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
+use crate::ops::Try;
+
+/// An iterator that maps the values of `iter` with `f`.
+///
+/// This `struct` is created by the [`map`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`map`]: Iterator::map
+/// [`Iterator`]: trait.Iterator.html
+///
+/// # Notes about side effects
+///
+/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that
+/// you can also [`map`] backwards:
+///
+/// ```rust
+/// let v: Vec<i32> = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect();
+///
+/// assert_eq!(v, [4, 3, 2]);
+/// ```
+///
+/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
+///
+/// But if your closure has state, iterating backwards may act in a way you do
+/// not expect. Let's go through an example. First, in the forward direction:
+///
+/// ```rust
+/// let mut c = 0;
+///
+/// for pair in vec!['a', 'b', 'c'].into_iter()
+/// .map(|letter| { c += 1; (letter, c) }) {
+/// println!("{:?}", pair);
+/// }
+/// ```
+///
+/// This will print "('a', 1), ('b', 2), ('c', 3)".
+///
+/// Now consider this twist where we add a call to `rev`. This version will
+/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
+/// but the values of the counter still go in order. This is because `map()` is
+/// still being called lazily on each item, but we are popping items off the
+/// back of the vector now, instead of shifting them from the front.
+///
+/// ```rust
+/// let mut c = 0;
+///
+/// for pair in vec!['a', 'b', 'c'].into_iter()
+/// .map(|letter| { c += 1; (letter, c) })
+/// .rev() {
+/// println!("{:?}", pair);
+/// }
+/// ```
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct Map<I, F> {
+ iter: I,
+ f: F,
+}
+impl<I, F> Map<I, F> {
+ pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
+ Map { iter, f }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Map").field("iter", &self.iter).finish()
+ }
+}
+
+fn map_fold<T, B, Acc>(
+ mut f: impl FnMut(T) -> B,
+ mut g: impl FnMut(Acc, B) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+ move |acc, elt| g(acc, f(elt))
+}
+
+fn map_try_fold<'a, T, B, Acc, R>(
+ f: &'a mut impl FnMut(T) -> B,
+ mut g: impl FnMut(Acc, B) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+ move |acc, elt| g(acc, f(elt))
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I: Iterator, F> Iterator for Map<I, F>
+where
+ F: FnMut(I::Item) -> B,
+{
+ type Item = B;
+
+ #[inline]
+ fn next(&mut self) -> Option<B> {
+ self.iter.next().map(&mut self.f)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
+ where
+ Self: Sized,
+ G: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_fold(init, map_try_fold(&mut self.f, g))
+ }
+
+ fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(init, map_fold(self.f, g))
+ }
+
+ unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
+ where
+ Self: TrustedRandomAccess,
+ {
+ // SAFETY: the caller must uphold the contract for
+ // `Iterator::__iterator_get_unchecked`.
+ unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>
+where
+ F: FnMut(I::Item) -> B,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<B> {
+ self.iter.next_back().map(&mut self.f)
+ }
+
+ fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
+ where
+ Self: Sized,
+ G: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ self.iter.try_rfold(init, map_try_fold(&mut self.f, g))
+ }
+
+ fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.rfold(init, map_fold(self.f, g))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
+where
+ F: FnMut(I::Item) -> B,
+{
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<B, I: FusedIterator, F> FusedIterator for Map<I, F> where F: FnMut(I::Item) -> B {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<B, I, F> TrustedLen for Map<I, F>
+where
+ I: TrustedLen,
+ F: FnMut(I::Item) -> B,
+{
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
+where
+ I: TrustedRandomAccess,
+{
+ #[inline]
+ fn may_have_side_effect() -> bool {
+ true
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for Map<I, F>
+where
+ F: FnMut(I::Item) -> B,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for Map<I, F> where F: FnMut(I::Item) -> B {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, InPlaceIterable};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator that only accepts elements while `predicate` returns `Some(_)`.
+///
+/// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`map_while`]: Iterator::map_while
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+#[derive(Clone)]
+pub struct MapWhile<I, P> {
+ iter: I,
+ predicate: P,
+}
+
+impl<I, P> MapWhile<I, P> {
+ pub(in crate::iter) fn new(iter: I, predicate: P) -> MapWhile<I, P> {
+ MapWhile { iter, predicate }
+ }
+}
+
+#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("MapWhile").field("iter", &self.iter).finish()
+ }
+}
+
+#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
+where
+ P: FnMut(I::Item) -> Option<B>,
+{
+ type Item = B;
+
+ #[inline]
+ fn next(&mut self) -> Option<B> {
+ let x = self.iter.next()?;
+ (self.predicate)(x)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the predicate
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ let Self { iter, predicate } = self;
+ iter.try_fold(init, |acc, x| match predicate(x) {
+ Some(item) => ControlFlow::from_try(fold(acc, item)),
+ None => ControlFlow::Break(try { acc }),
+ })
+ .into_try()
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+ move |acc, x| Ok(f(acc, x))
+ }
+
+ self.try_fold(init, ok(fold)).unwrap()
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, B, I: Iterator, P> SourceIter for MapWhile<I, P>
+where
+ P: FnMut(I::Item) -> Option<B>,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<B, I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> where
+ P: FnMut(I::Item) -> Option<B>
+{
+}
-use crate::cmp;
-use crate::fmt;
-use crate::intrinsics;
-use crate::ops::{Add, AddAssign, ControlFlow, Try};
-
-use super::from_fn;
-use super::{
- DoubleEndedIterator, ExactSizeIterator, FusedIterator, InPlaceIterable, Iterator, TrustedLen,
-};
+use crate::iter::{InPlaceIterable, Iterator};
+use crate::ops::{ControlFlow, Try};
mod chain;
+mod cloned;
+mod copied;
+mod cycle;
+mod enumerate;
+mod filter;
+mod filter_map;
mod flatten;
mod fuse;
+mod inspect;
+mod map;
+mod map_while;
+mod peekable;
+mod rev;
+mod scan;
+mod skip;
+mod skip_while;
+mod step_by;
+mod take;
+mod take_while;
mod zip;
-pub use self::chain::Chain;
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::flatten::{FlatMap, Flatten};
-pub use self::fuse::Fuse;
-use self::zip::try_get_unchecked;
+pub use self::{
+ chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
+ flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
+ scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
+};
+
+#[stable(feature = "iter_cloned", since = "1.1.0")]
+pub use self::cloned::Cloned;
+
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
+pub use self::step_by::StepBy;
+
+#[stable(feature = "iterator_flatten", since = "1.29.0")]
+pub use self::flatten::Flatten;
+
+#[stable(feature = "iter_copied", since = "1.36.0")]
+pub use self::copied::Copied;
+
+#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
+pub use self::map_while::MapWhile;
+
#[unstable(feature = "trusted_random_access", issue = "none")]
pub use self::zip::TrustedRandomAccess;
-pub use self::zip::Zip;
/// This trait provides transitive access to source-stage in an interator-adapter pipeline
/// under the conditions that
unsafe fn as_inner(&mut self) -> &mut Self::Source;
}
-/// A double-ended iterator with the direction inverted.
-///
-/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`rev`]: Iterator::rev
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Rev<T> {
- iter: T,
-}
-impl<T> Rev<T> {
- pub(super) fn new(iter: T) -> Rev<T> {
- Rev { iter }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> Iterator for Rev<I>
-where
- I: DoubleEndedIterator,
-{
- type Item = <I as Iterator>::Item;
-
- #[inline]
- fn next(&mut self) -> Option<<I as Iterator>::Item> {
- self.iter.next_back()
- }
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- #[inline]
- fn advance_by(&mut self, n: usize) -> Result<(), usize> {
- self.iter.advance_back_by(n)
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
- self.iter.nth_back(n)
- }
-
- fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.iter.try_rfold(init, f)
- }
-
- fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.rfold(init, f)
- }
-
- #[inline]
- fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
- where
- P: FnMut(&Self::Item) -> bool,
- {
- self.iter.rfind(predicate)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> DoubleEndedIterator for Rev<I>
-where
- I: DoubleEndedIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
- self.iter.next()
- }
-
- #[inline]
- fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
- self.iter.advance_by(n)
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
- self.iter.nth(n)
- }
-
- fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.iter.try_fold(init, f)
- }
-
- fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.fold(init, f)
- }
-
- fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
- where
- P: FnMut(&Self::Item) -> bool,
- {
- self.iter.find(predicate)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Rev<I>
-where
- I: ExactSizeIterator + DoubleEndedIterator,
-{
- fn len(&self) -> usize {
- self.iter.len()
- }
-
- fn is_empty(&self) -> bool {
- self.iter.is_empty()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> FusedIterator for Rev<I> where I: FusedIterator + DoubleEndedIterator {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator {}
-
-/// An iterator that copies the elements of an underlying iterator.
-///
-/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`copied`]: Iterator::copied
-/// [`Iterator`]: trait.Iterator.html
-#[stable(feature = "iter_copied", since = "1.36.0")]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[derive(Clone, Debug)]
-pub struct Copied<I> {
- it: I,
-}
-
-impl<I> Copied<I> {
- pub(super) fn new(it: I) -> Copied<I> {
- Copied { it }
- }
-}
-
-fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
- move |acc, &elt| f(acc, elt)
-}
-
-fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
- move |acc, &elt| f(acc, elt)
-}
-
-#[stable(feature = "iter_copied", since = "1.36.0")]
-impl<'a, I, T: 'a> Iterator for Copied<I>
-where
- I: Iterator<Item = &'a T>,
- T: Copy,
-{
- type Item = T;
-
- fn next(&mut self) -> Option<T> {
- self.it.next().copied()
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.it.size_hint()
- }
-
- fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.it.try_fold(init, copy_try_fold(f))
- }
-
- fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.it.fold(init, copy_fold(f))
- }
-
- fn nth(&mut self, n: usize) -> Option<T> {
- self.it.nth(n).copied()
- }
-
- fn last(self) -> Option<T> {
- self.it.last().copied()
- }
-
- fn count(self) -> usize {
- self.it.count()
- }
-
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
- where
- Self: TrustedRandomAccess,
- {
- // SAFETY: the caller must uphold the contract for
- // `Iterator::__iterator_get_unchecked`.
- *unsafe { try_get_unchecked(&mut self.it, idx) }
- }
-}
-
-#[stable(feature = "iter_copied", since = "1.36.0")]
-impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
-where
- I: DoubleEndedIterator<Item = &'a T>,
- T: Copy,
-{
- fn next_back(&mut self) -> Option<T> {
- self.it.next_back().copied()
- }
-
- fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.it.try_rfold(init, copy_try_fold(f))
- }
-
- fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.it.rfold(init, copy_fold(f))
- }
-}
-
-#[stable(feature = "iter_copied", since = "1.36.0")]
-impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
-where
- I: ExactSizeIterator<Item = &'a T>,
- T: Copy,
-{
- fn len(&self) -> usize {
- self.it.len()
- }
-
- fn is_empty(&self) -> bool {
- self.it.is_empty()
- }
-}
-
-#[stable(feature = "iter_copied", since = "1.36.0")]
-impl<'a, I, T: 'a> FusedIterator for Copied<I>
-where
- I: FusedIterator<Item = &'a T>,
- T: Copy,
-{
-}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Copied<I>
-where
- I: TrustedRandomAccess,
-{
- #[inline]
- fn may_have_side_effect() -> bool {
- I::may_have_side_effect()
- }
-}
-
-#[stable(feature = "iter_copied", since = "1.36.0")]
-unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
-where
- I: TrustedLen<Item = &'a T>,
- T: Copy,
-{
-}
-
-/// An iterator that clones the elements of an underlying iterator.
-///
-/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`cloned`]: Iterator::cloned
-/// [`Iterator`]: trait.Iterator.html
-#[stable(feature = "iter_cloned", since = "1.1.0")]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[derive(Clone, Debug)]
-pub struct Cloned<I> {
- it: I,
-}
-impl<I> Cloned<I> {
- pub(super) fn new(it: I) -> Cloned<I> {
- Cloned { it }
- }
-}
-
-fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
- move |acc, elt| f(acc, elt.clone())
-}
-
-#[stable(feature = "iter_cloned", since = "1.1.0")]
-impl<'a, I, T: 'a> Iterator for Cloned<I>
-where
- I: Iterator<Item = &'a T>,
- T: Clone,
-{
- type Item = T;
-
- fn next(&mut self) -> Option<T> {
- self.it.next().cloned()
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.it.size_hint()
- }
-
- fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.it.try_fold(init, clone_try_fold(f))
- }
-
- fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.it.map(T::clone).fold(init, f)
- }
-
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
- where
- Self: TrustedRandomAccess,
- {
- // SAFETY: the caller must uphold the contract for
- // `Iterator::__iterator_get_unchecked`.
- unsafe { try_get_unchecked(&mut self.it, idx).clone() }
- }
-}
-
-#[stable(feature = "iter_cloned", since = "1.1.0")]
-impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
-where
- I: DoubleEndedIterator<Item = &'a T>,
- T: Clone,
-{
- fn next_back(&mut self) -> Option<T> {
- self.it.next_back().cloned()
- }
-
- fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- self.it.try_rfold(init, clone_try_fold(f))
- }
-
- fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- self.it.map(T::clone).rfold(init, f)
- }
-}
-
-#[stable(feature = "iter_cloned", since = "1.1.0")]
-impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
-where
- I: ExactSizeIterator<Item = &'a T>,
- T: Clone,
-{
- fn len(&self) -> usize {
- self.it.len()
- }
-
- fn is_empty(&self) -> bool {
- self.it.is_empty()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, I, T: 'a> FusedIterator for Cloned<I>
-where
- I: FusedIterator<Item = &'a T>,
- T: Clone,
-{
-}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Cloned<I>
-where
- I: TrustedRandomAccess,
-{
- #[inline]
- fn may_have_side_effect() -> bool {
- true
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
-where
- I: TrustedLen<Item = &'a T>,
- T: Clone,
-{
-}
-
-/// An iterator that repeats endlessly.
-///
-/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`cycle`]: Iterator::cycle
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Cycle<I> {
- orig: I,
- iter: I,
-}
-impl<I: Clone> Cycle<I> {
- pub(super) fn new(iter: I) -> Cycle<I> {
- Cycle { orig: iter.clone(), iter }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> Iterator for Cycle<I>
-where
- I: Clone + Iterator,
-{
- type Item = <I as Iterator>::Item;
-
- #[inline]
- fn next(&mut self) -> Option<<I as Iterator>::Item> {
- match self.iter.next() {
- None => {
- self.iter = self.orig.clone();
- self.iter.next()
- }
- y => y,
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- // the cycle iterator is either empty or infinite
- match self.orig.size_hint() {
- sz @ (0, Some(0)) => sz,
- (0, _) => (0, None),
- _ => (usize::MAX, None),
- }
- }
-
- #[inline]
- fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
- where
- F: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- // fully iterate the current iterator. this is necessary because
- // `self.iter` may be empty even when `self.orig` isn't
- acc = self.iter.try_fold(acc, &mut f)?;
- self.iter = self.orig.clone();
-
- // complete a full cycle, keeping track of whether the cycled
- // iterator is empty or not. we need to return early in case
- // of an empty iterator to prevent an infinite loop
- let mut is_empty = true;
- acc = self.iter.try_fold(acc, |acc, x| {
- is_empty = false;
- f(acc, x)
- })?;
-
- if is_empty {
- return try { acc };
- }
-
- loop {
- self.iter = self.orig.clone();
- acc = self.iter.try_fold(acc, &mut f)?;
- }
- }
-
- // No `fold` override, because `fold` doesn't make much sense for `Cycle`,
- // and we can't do anything better than the default.
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
-
-/// An iterator for stepping iterators by a custom amount.
-///
-/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See
-/// its documentation for more.
-///
-/// [`step_by`]: Iterator::step_by
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "iterator_step_by", since = "1.28.0")]
-#[derive(Clone, Debug)]
-pub struct StepBy<I> {
- iter: I,
- step: usize,
- first_take: bool,
-}
-impl<I> StepBy<I> {
- pub(super) fn new(iter: I, step: usize) -> StepBy<I> {
- assert!(step != 0);
- StepBy { iter, step: step - 1, first_take: true }
- }
-}
-
-#[stable(feature = "iterator_step_by", since = "1.28.0")]
-impl<I> Iterator for StepBy<I>
-where
- I: Iterator,
-{
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- if self.first_take {
- self.first_take = false;
- self.iter.next()
- } else {
- self.iter.nth(self.step)
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- #[inline]
- fn first_size(step: usize) -> impl Fn(usize) -> usize {
- move |n| if n == 0 { 0 } else { 1 + (n - 1) / (step + 1) }
- }
-
- #[inline]
- fn other_size(step: usize) -> impl Fn(usize) -> usize {
- move |n| n / (step + 1)
- }
-
- let (low, high) = self.iter.size_hint();
-
- if self.first_take {
- let f = first_size(self.step);
- (f(low), high.map(f))
- } else {
- let f = other_size(self.step);
- (f(low), high.map(f))
- }
- }
-
- #[inline]
- fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
- if self.first_take {
- self.first_take = false;
- let first = self.iter.next();
- if n == 0 {
- return first;
- }
- n -= 1;
- }
- // n and self.step are indices, we need to add 1 to get the amount of elements
- // When calling `.nth`, we need to subtract 1 again to convert back to an index
- // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1`
- let mut step = self.step + 1;
- // n + 1 could overflow
- // thus, if n is usize::MAX, instead of adding one, we call .nth(step)
- if n == usize::MAX {
- self.iter.nth(step - 1);
- } else {
- n += 1;
- }
-
- // overflow handling
- loop {
- let mul = n.checked_mul(step);
- {
- if intrinsics::likely(mul.is_some()) {
- return self.iter.nth(mul.unwrap() - 1);
- }
- }
- let div_n = usize::MAX / n;
- let div_step = usize::MAX / step;
- let nth_n = div_n * n;
- let nth_step = div_step * step;
- let nth = if nth_n > nth_step {
- step -= div_n;
- nth_n
- } else {
- n -= div_step;
- nth_step
- };
- self.iter.nth(nth - 1);
- }
- }
-
- fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
- where
- F: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- #[inline]
- fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
- move || iter.nth(step)
- }
-
- if self.first_take {
- self.first_take = false;
- match self.iter.next() {
- None => return try { acc },
- Some(x) => acc = f(acc, x)?,
- }
- }
- from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
- }
-
- fn fold<Acc, F>(mut self, mut acc: Acc, mut f: F) -> Acc
- where
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
- move || iter.nth(step)
- }
-
- if self.first_take {
- self.first_take = false;
- match self.iter.next() {
- None => return acc,
- Some(x) => acc = f(acc, x),
- }
- }
- from_fn(nth(&mut self.iter, self.step)).fold(acc, f)
- }
-}
-
-impl<I> StepBy<I>
-where
- I: ExactSizeIterator,
-{
- // The zero-based index starting from the end of the iterator of the
- // last element. Used in the `DoubleEndedIterator` implementation.
- fn next_back_index(&self) -> usize {
- let rem = self.iter.len() % (self.step + 1);
- if self.first_take {
- if rem == 0 { self.step } else { rem - 1 }
- } else {
- rem
- }
- }
-}
-
-#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
-impl<I> DoubleEndedIterator for StepBy<I>
-where
- I: DoubleEndedIterator + ExactSizeIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<Self::Item> {
- self.iter.nth_back(self.next_back_index())
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
- // is out of bounds because the length of `self.iter` does not exceed
- // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
- // zero-indexed
- let n = n.saturating_mul(self.step + 1).saturating_add(self.next_back_index());
- self.iter.nth_back(n)
- }
-
- fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
- where
- F: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- #[inline]
- fn nth_back<I: DoubleEndedIterator>(
- iter: &mut I,
- step: usize,
- ) -> impl FnMut() -> Option<I::Item> + '_ {
- move || iter.nth_back(step)
- }
-
- match self.next_back() {
- None => try { init },
- Some(x) => {
- let acc = f(init, x)?;
- from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
- }
- }
- }
-
- #[inline]
- fn rfold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc
- where
- Self: Sized,
- F: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn nth_back<I: DoubleEndedIterator>(
- iter: &mut I,
- step: usize,
- ) -> impl FnMut() -> Option<I::Item> + '_ {
- move || iter.nth_back(step)
- }
-
- match self.next_back() {
- None => init,
- Some(x) => {
- let acc = f(init, x);
- from_fn(nth_back(&mut self.iter, self.step)).fold(acc, f)
- }
- }
- }
-}
-
-// StepBy can only make the iterator shorter, so the len will still fit.
-#[stable(feature = "iterator_step_by", since = "1.28.0")]
-impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
-
-/// An iterator that maps the values of `iter` with `f`.
-///
-/// This `struct` is created by the [`map`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`map`]: Iterator::map
-/// [`Iterator`]: trait.Iterator.html
-///
-/// # Notes about side effects
-///
-/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that
-/// you can also [`map`] backwards:
-///
-/// ```rust
-/// let v: Vec<i32> = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect();
-///
-/// assert_eq!(v, [4, 3, 2]);
-/// ```
-///
-/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
-///
-/// But if your closure has state, iterating backwards may act in a way you do
-/// not expect. Let's go through an example. First, in the forward direction:
-///
-/// ```rust
-/// let mut c = 0;
-///
-/// for pair in vec!['a', 'b', 'c'].into_iter()
-/// .map(|letter| { c += 1; (letter, c) }) {
-/// println!("{:?}", pair);
-/// }
-/// ```
-///
-/// This will print "('a', 1), ('b', 2), ('c', 3)".
-///
-/// Now consider this twist where we add a call to `rev`. This version will
-/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
-/// but the values of the counter still go in order. This is because `map()` is
-/// still being called lazily on each item, but we are popping items off the
-/// back of the vector now, instead of shifting them from the front.
-///
-/// ```rust
-/// let mut c = 0;
-///
-/// for pair in vec!['a', 'b', 'c'].into_iter()
-/// .map(|letter| { c += 1; (letter, c) })
-/// .rev() {
-/// println!("{:?}", pair);
-/// }
-/// ```
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct Map<I, F> {
- iter: I,
- f: F,
-}
-impl<I, F> Map<I, F> {
- pub(super) fn new(iter: I, f: F) -> Map<I, F> {
- Map { iter, f }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Map").field("iter", &self.iter).finish()
- }
-}
-
-fn map_fold<T, B, Acc>(
- mut f: impl FnMut(T) -> B,
- mut g: impl FnMut(Acc, B) -> Acc,
-) -> impl FnMut(Acc, T) -> Acc {
- move |acc, elt| g(acc, f(elt))
-}
-
-fn map_try_fold<'a, T, B, Acc, R>(
- f: &'a mut impl FnMut(T) -> B,
- mut g: impl FnMut(Acc, B) -> R + 'a,
-) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, elt| g(acc, f(elt))
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, F> Iterator for Map<I, F>
-where
- F: FnMut(I::Item) -> B,
-{
- type Item = B;
-
- #[inline]
- fn next(&mut self) -> Option<B> {
- self.iter.next().map(&mut self.f)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
- where
- Self: Sized,
- G: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_fold(init, map_try_fold(&mut self.f, g))
- }
-
- fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
- where
- G: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.fold(init, map_fold(self.f, g))
- }
-
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
- where
- Self: TrustedRandomAccess,
- {
- // SAFETY: the caller must uphold the contract for
- // `Iterator::__iterator_get_unchecked`.
- unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>
-where
- F: FnMut(I::Item) -> B,
-{
- #[inline]
- fn next_back(&mut self) -> Option<B> {
- self.iter.next_back().map(&mut self.f)
- }
-
- fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
- where
- Self: Sized,
- G: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_rfold(init, map_try_fold(&mut self.f, g))
- }
-
- fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
- where
- G: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.rfold(init, map_fold(self.f, g))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
-where
- F: FnMut(I::Item) -> B,
-{
- fn len(&self) -> usize {
- self.iter.len()
- }
-
- fn is_empty(&self) -> bool {
- self.iter.is_empty()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<B, I: FusedIterator, F> FusedIterator for Map<I, F> where F: FnMut(I::Item) -> B {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<B, I, F> TrustedLen for Map<I, F>
-where
- I: TrustedLen,
- F: FnMut(I::Item) -> B,
-{
-}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
-where
- I: TrustedRandomAccess,
-{
- #[inline]
- fn may_have_side_effect() -> bool {
- true
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for Map<I, F>
-where
- F: FnMut(I::Item) -> B,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for Map<I, F> where F: FnMut(I::Item) -> B {}
-
-/// An iterator that filters the elements of `iter` with `predicate`.
-///
-/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`filter`]: Iterator::filter
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct Filter<I, P> {
- iter: I,
- predicate: P,
-}
-impl<I, P> Filter<I, P> {
- pub(super) fn new(iter: I, predicate: P) -> Filter<I, P> {
- Filter { iter, predicate }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Filter").field("iter", &self.iter).finish()
- }
-}
-
-fn filter_fold<T, Acc>(
- mut predicate: impl FnMut(&T) -> bool,
- mut fold: impl FnMut(Acc, T) -> Acc,
-) -> impl FnMut(Acc, T) -> Acc {
- move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
-}
-
-fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
- predicate: &'a mut impl FnMut(&T) -> bool,
- mut fold: impl FnMut(Acc, T) -> R + 'a,
-) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, item| if predicate(&item) { fold(acc, item) } else { try { acc } }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for Filter<I, P>
-where
- P: FnMut(&I::Item) -> bool,
-{
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- self.iter.find(&mut self.predicate)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-
- // this special case allows the compiler to make `.filter(_).count()`
- // branchless. Barring perfect branch prediction (which is unattainable in
- // the general case), this will be much faster in >90% of cases (containing
- // virtually all real workloads) and only a tiny bit slower in the rest.
- //
- // Having this specialization thus allows us to write `.filter(p).count()`
- // where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is
- // less readable and also less backwards-compatible to Rust before 1.10.
- //
- // Using the branchless version will also simplify the LLVM byte code, thus
- // leaving more budget for LLVM optimizations.
- #[inline]
- fn count(self) -> usize {
- #[inline]
- fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
- move |x| predicate(&x) as usize
- }
-
- self.iter.map(to_usize(self.predicate)).sum()
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.fold(init, filter_fold(self.predicate, fold))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
-where
- P: FnMut(&I::Item) -> bool,
-{
- #[inline]
- fn next_back(&mut self) -> Option<I::Item> {
- self.iter.rfind(&mut self.predicate)
- }
-
- #[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
- }
-
- #[inline]
- fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.rfold(init, filter_fold(self.predicate, fold))
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P>
-where
- P: FnMut(&I::Item) -> bool,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {}
-
-/// An iterator that uses `f` to both filter and map elements from `iter`.
-///
-/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`filter_map`]: Iterator::filter_map
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct FilterMap<I, F> {
- iter: I,
- f: F,
-}
-impl<I, F> FilterMap<I, F> {
- pub(super) fn new(iter: I, f: F) -> FilterMap<I, F> {
- FilterMap { iter, f }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FilterMap").field("iter", &self.iter).finish()
- }
-}
-
-fn filter_map_fold<T, B, Acc>(
- mut f: impl FnMut(T) -> Option<B>,
- mut fold: impl FnMut(Acc, B) -> Acc,
-) -> impl FnMut(Acc, T) -> Acc {
- move |acc, item| match f(item) {
- Some(x) => fold(acc, x),
- None => acc,
- }
-}
-
-fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
- f: &'a mut impl FnMut(T) -> Option<B>,
- mut fold: impl FnMut(Acc, B) -> R + 'a,
-) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, item| match f(item) {
- Some(x) => fold(acc, x),
- None => try { acc },
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
-where
- F: FnMut(I::Item) -> Option<B>,
-{
- type Item = B;
-
- #[inline]
- fn next(&mut self) -> Option<B> {
- self.iter.find_map(&mut self.f)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.fold(init, filter_map_fold(self.f, fold))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
-where
- F: FnMut(I::Item) -> Option<B>,
-{
- #[inline]
- fn next_back(&mut self) -> Option<B> {
- #[inline]
- fn find<T, B>(
- f: &mut impl FnMut(T) -> Option<B>,
- ) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
- move |(), x| match f(x) {
- Some(x) => ControlFlow::Break(x),
- None => ControlFlow::CONTINUE,
- }
- }
-
- self.iter.try_rfold((), find(&mut self.f)).break_value()
- }
-
- #[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
- }
-
- #[inline]
- fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.rfold(init, filter_map_fold(self.f, fold))
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F>
-where
- F: FnMut(I::Item) -> Option<B>,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where
- F: FnMut(I::Item) -> Option<B>
-{
-}
-
-/// An iterator that yields the current count and the element during iteration.
-///
-/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`enumerate`]: Iterator::enumerate
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Enumerate<I> {
- iter: I,
- count: usize,
-}
-impl<I> Enumerate<I> {
- pub(super) fn new(iter: I) -> Enumerate<I> {
- Enumerate { iter, count: 0 }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> Iterator for Enumerate<I>
-where
- I: Iterator,
-{
- type Item = (usize, <I as Iterator>::Item);
-
- /// # Overflow Behavior
- ///
- /// The method does no guarding against overflows, so enumerating more than
- /// `usize::MAX` elements either produces the wrong result or panics. If
- /// debug assertions are enabled, a panic is guaranteed.
- ///
- /// # Panics
- ///
- /// Might panic if the index of the element overflows a `usize`.
- #[inline]
- fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
- let a = self.iter.next()?;
- let i = self.count;
- // Possible undefined overflow.
- AddAssign::add_assign(&mut self.count, 1);
- Some((i, a))
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
- let a = self.iter.nth(n)?;
- // Possible undefined overflow.
- let i = Add::add(self.count, n);
- self.count = Add::add(i, 1);
- Some((i, a))
- }
-
- #[inline]
- fn count(self) -> usize {
- self.iter.count()
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- #[inline]
- fn enumerate<'a, T, Acc, R>(
- count: &'a mut usize,
- mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, item| {
- let acc = fold(acc, (*count, item));
- // Possible undefined overflow.
- AddAssign::add_assign(count, 1);
- acc
- }
- }
-
- self.iter.try_fold(init, enumerate(&mut self.count, fold))
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn enumerate<T, Acc>(
- mut count: usize,
- mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
- ) -> impl FnMut(Acc, T) -> Acc {
- move |acc, item| {
- let acc = fold(acc, (count, item));
- // Possible undefined overflow.
- AddAssign::add_assign(&mut count, 1);
- acc
- }
- }
-
- self.iter.fold(init, enumerate(self.count, fold))
- }
-
- unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
- where
- Self: TrustedRandomAccess,
- {
- // SAFETY: the caller must uphold the contract for
- // `Iterator::__iterator_get_unchecked`.
- let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
- (Add::add(self.count, idx), value)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> DoubleEndedIterator for Enumerate<I>
-where
- I: ExactSizeIterator + DoubleEndedIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
- let a = self.iter.next_back()?;
- let len = self.iter.len();
- // Can safely add, `ExactSizeIterator` promises that the number of
- // elements fits into a `usize`.
- Some((self.count + len, a))
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
- let a = self.iter.nth_back(n)?;
- let len = self.iter.len();
- // Can safely add, `ExactSizeIterator` promises that the number of
- // elements fits into a `usize`.
- Some((self.count + len, a))
- }
-
- #[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- // Can safely add and subtract the count, as `ExactSizeIterator` promises
- // that the number of elements fits into a `usize`.
- fn enumerate<T, Acc, R>(
- mut count: usize,
- mut fold: impl FnMut(Acc, (usize, T)) -> R,
- ) -> impl FnMut(Acc, T) -> R {
- move |acc, item| {
- count -= 1;
- fold(acc, (count, item))
- }
- }
-
- let count = self.count + self.iter.len();
- self.iter.try_rfold(init, enumerate(count, fold))
- }
-
- #[inline]
- fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- // Can safely add and subtract the count, as `ExactSizeIterator` promises
- // that the number of elements fits into a `usize`.
- fn enumerate<T, Acc>(
- mut count: usize,
- mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
- ) -> impl FnMut(Acc, T) -> Acc {
- move |acc, item| {
- count -= 1;
- fold(acc, (count, item))
- }
- }
-
- let count = self.count + self.iter.len();
- self.iter.rfold(init, enumerate(count, fold))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Enumerate<I>
-where
- I: ExactSizeIterator,
-{
- fn len(&self) -> usize {
- self.iter.len()
- }
-
- fn is_empty(&self) -> bool {
- self.iter.is_empty()
- }
-}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Enumerate<I>
-where
- I: TrustedRandomAccess,
-{
- fn may_have_side_effect() -> bool {
- I::may_have_side_effect()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
-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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}
-
-/// An iterator with a `peek()` that returns an optional reference to the next
-/// element.
-///
-/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`peekable`]: Iterator::peekable
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Peekable<I: Iterator> {
- iter: I,
- /// Remember a peeked value, even if it was None.
- peeked: Option<Option<I::Item>>,
-}
-impl<I: Iterator> Peekable<I> {
- pub(super) fn new(iter: I) -> Peekable<I> {
- Peekable { iter, peeked: None }
- }
-}
-
-// Peekable must remember if a None has been seen in the `.peek()` method.
-// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the
-// underlying iterator at most once. This does not by itself make the iterator
-// fused.
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator> Iterator for Peekable<I> {
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- match self.peeked.take() {
- Some(v) => v,
- None => self.iter.next(),
- }
- }
-
- #[inline]
- #[rustc_inherit_overflow_checks]
- fn count(mut self) -> usize {
- match self.peeked.take() {
- Some(None) => 0,
- Some(Some(_)) => 1 + self.iter.count(),
- None => self.iter.count(),
- }
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<I::Item> {
- match self.peeked.take() {
- Some(None) => None,
- Some(v @ Some(_)) if n == 0 => v,
- Some(Some(_)) => self.iter.nth(n - 1),
- None => self.iter.nth(n),
- }
- }
-
- #[inline]
- fn last(mut self) -> Option<I::Item> {
- let peek_opt = match self.peeked.take() {
- Some(None) => return None,
- Some(v) => v,
- None => None,
- };
- self.iter.last().or(peek_opt)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let peek_len = match self.peeked {
- Some(None) => return (0, Some(0)),
- Some(Some(_)) => 1,
- None => 0,
- };
- let (lo, hi) = self.iter.size_hint();
- let lo = lo.saturating_add(peek_len);
- let hi = match hi {
- Some(x) => x.checked_add(peek_len),
- None => None,
- };
- (lo, hi)
- }
-
- #[inline]
- fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- let acc = match self.peeked.take() {
- Some(None) => return try { init },
- Some(Some(v)) => f(init, v)?,
- None => init,
- };
- self.iter.try_fold(acc, f)
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- let acc = match self.peeked {
- Some(None) => return init,
- Some(Some(v)) => fold(init, v),
- None => init,
- };
- self.iter.fold(acc, fold)
- }
-}
-
-#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
-impl<I> DoubleEndedIterator for Peekable<I>
-where
- I: DoubleEndedIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<Self::Item> {
- match self.peeked.as_mut() {
- Some(v @ Some(_)) => self.iter.next_back().or_else(|| v.take()),
- Some(None) => None,
- None => self.iter.next_back(),
- }
- }
-
- #[inline]
- fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
- where
- Self: Sized,
- F: FnMut(B, Self::Item) -> R,
- R: Try<Ok = B>,
- {
- match self.peeked.take() {
- Some(None) => try { init },
- Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
- Ok(acc) => f(acc, v),
- Err(e) => {
- self.peeked = Some(Some(v));
- Try::from_error(e)
- }
- },
- None => self.iter.try_rfold(init, f),
- }
- }
-
- #[inline]
- fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- match self.peeked {
- Some(None) => init,
- Some(Some(v)) => {
- let acc = self.iter.rfold(init, &mut fold);
- fold(acc, v)
- }
- None => self.iter.rfold(init, fold),
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I: FusedIterator> FusedIterator for Peekable<I> {}
-
-impl<I: Iterator> Peekable<I> {
- /// Returns a reference to the next() value without advancing the iterator.
- ///
- /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`.
- /// But if the iteration is over, `None` is returned.
- ///
- /// [`next`]: Iterator::next
- ///
- /// Because `peek()` returns a reference, and many iterators iterate over
- /// references, there can be a possibly confusing situation where the
- /// return value is a double reference. You can see this effect in the
- /// examples below.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let xs = [1, 2, 3];
- ///
- /// let mut iter = xs.iter().peekable();
- ///
- /// // peek() lets us see into the future
- /// assert_eq!(iter.peek(), Some(&&1));
- /// assert_eq!(iter.next(), Some(&1));
- ///
- /// assert_eq!(iter.next(), Some(&2));
- ///
- /// // The iterator does not advance even if we `peek` multiple times
- /// assert_eq!(iter.peek(), Some(&&3));
- /// assert_eq!(iter.peek(), Some(&&3));
- ///
- /// assert_eq!(iter.next(), Some(&3));
- ///
- /// // After the iterator is finished, so is `peek()`
- /// assert_eq!(iter.peek(), None);
- /// assert_eq!(iter.next(), None);
- /// ```
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn peek(&mut self) -> Option<&I::Item> {
- let iter = &mut self.iter;
- self.peeked.get_or_insert_with(|| iter.next()).as_ref()
- }
-
- /// Consume and return the next value of this iterator if a condition is true.
- ///
- /// If `func` returns `true` for the next value of this iterator, consume and return it.
- /// Otherwise, return `None`.
- ///
- /// # Examples
- /// Consume a number if it's equal to 0.
- /// ```
- /// #![feature(peekable_next_if)]
- /// let mut iter = (0..5).peekable();
- /// // The first item of the iterator is 0; consume it.
- /// assert_eq!(iter.next_if(|&x| x == 0), Some(0));
- /// // The next item returned is now 1, so `consume` will return `false`.
- /// assert_eq!(iter.next_if(|&x| x == 0), None);
- /// // `next_if` saves the value of the next item if it was not equal to `expected`.
- /// assert_eq!(iter.next(), Some(1));
- /// ```
- ///
- /// Consume any number less than 10.
- /// ```
- /// #![feature(peekable_next_if)]
- /// let mut iter = (1..20).peekable();
- /// // Consume all numbers less than 10
- /// while iter.next_if(|&x| x < 10).is_some() {}
- /// // The next value returned will be 10
- /// assert_eq!(iter.next(), Some(10));
- /// ```
- #[unstable(feature = "peekable_next_if", issue = "72480")]
- pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
- match self.next() {
- Some(matched) if func(&matched) => Some(matched),
- other => {
- // Since we called `self.next()`, we consumed `self.peeked`.
- assert!(self.peeked.is_none());
- self.peeked = Some(other);
- None
- }
- }
- }
-
- /// Consume and return the next item if it is equal to `expected`.
- ///
- /// # Example
- /// Consume a number if it's equal to 0.
- /// ```
- /// #![feature(peekable_next_if)]
- /// let mut iter = (0..5).peekable();
- /// // The first item of the iterator is 0; consume it.
- /// assert_eq!(iter.next_if_eq(&0), Some(0));
- /// // The next item returned is now 1, so `consume` will return `false`.
- /// assert_eq!(iter.next_if_eq(&0), None);
- /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`.
- /// assert_eq!(iter.next(), Some(1));
- /// ```
- #[unstable(feature = "peekable_next_if", issue = "72480")]
- pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
- where
- T: ?Sized,
- I::Item: PartialEq<T>,
- {
- self.next_if(|next| next == expected)
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: Iterator> SourceIter for Peekable<I>
-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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}
-
-/// An iterator that rejects elements while `predicate` returns `true`.
-///
-/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`skip_while`]: Iterator::skip_while
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct SkipWhile<I, P> {
- iter: I,
- flag: bool,
- predicate: P,
-}
-impl<I, P> SkipWhile<I, P> {
- pub(super) fn new(iter: I, predicate: P) -> SkipWhile<I, P> {
- SkipWhile { iter, flag: false, predicate }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SkipWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for SkipWhile<I, P>
-where
- P: FnMut(&I::Item) -> bool,
-{
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- fn check<'a, T>(
- flag: &'a mut bool,
- pred: &'a mut impl FnMut(&T) -> bool,
- ) -> impl FnMut(&T) -> bool + 'a {
- move |x| {
- if *flag || !pred(x) {
- *flag = true;
- true
- } else {
- false
- }
- }
- }
-
- let flag = &mut self.flag;
- let pred = &mut self.predicate;
- self.iter.find(check(flag, pred))
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- if !self.flag {
- match self.next() {
- Some(v) => init = fold(init, v)?,
- None => return try { init },
- }
- }
- self.iter.try_fold(init, fold)
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, mut init: Acc, mut fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- if !self.flag {
- match self.next() {
- Some(v) => init = fold(init, v),
- None => return init,
- }
- }
- self.iter.fold(init, fold)
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I, P> FusedIterator for SkipWhile<I, P>
-where
- I: FusedIterator,
- P: FnMut(&I::Item) -> bool,
-{
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P>
-where
- P: FnMut(&I::Item) -> bool,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where
- F: FnMut(&I::Item) -> bool
-{
-}
-
-/// An iterator that only accepts elements while `predicate` returns `true`.
-///
-/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`take_while`]: Iterator::take_while
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct TakeWhile<I, P> {
- iter: I,
- flag: bool,
- predicate: P,
-}
-impl<I, P> TakeWhile<I, P> {
- pub(super) fn new(iter: I, predicate: P) -> TakeWhile<I, P> {
- TakeWhile { iter, flag: false, predicate }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("TakeWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for TakeWhile<I, P>
-where
- P: FnMut(&I::Item) -> bool,
-{
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- if self.flag {
- None
- } else {
- let x = self.iter.next()?;
- if (self.predicate)(&x) {
- Some(x)
- } else {
- self.flag = true;
- None
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.flag {
- (0, Some(0))
- } else {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- fn check<'a, T, Acc, R: Try<Ok = Acc>>(
- flag: &'a mut bool,
- p: &'a mut impl FnMut(&T) -> bool,
- mut fold: impl FnMut(Acc, T) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
- move |acc, x| {
- if p(&x) {
- ControlFlow::from_try(fold(acc, x))
- } else {
- *flag = true;
- ControlFlow::Break(try { acc })
- }
- }
- }
-
- if self.flag {
- try { init }
- } else {
- let flag = &mut self.flag;
- let p = &mut self.predicate;
- self.iter.try_fold(init, check(flag, p, fold)).into_try()
- }
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
- move |acc, x| Ok(f(acc, x))
- }
-
- self.try_fold(init, ok(fold)).unwrap()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I, P> FusedIterator for TakeWhile<I, P>
-where
- I: FusedIterator,
- P: FnMut(&I::Item) -> bool,
-{
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P>
-where
- P: FnMut(&I::Item) -> bool,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where
- F: FnMut(&I::Item) -> bool
-{
-}
-
-/// An iterator that only accepts elements while `predicate` returns `Some(_)`.
-///
-/// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`map_while`]: Iterator::map_while
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
-#[derive(Clone)]
-pub struct MapWhile<I, P> {
- iter: I,
- predicate: P,
-}
-
-impl<I, P> MapWhile<I, P> {
- pub(super) fn new(iter: I, predicate: P) -> MapWhile<I, P> {
- MapWhile { iter, predicate }
- }
-}
-
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
-impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("MapWhile").field("iter", &self.iter).finish()
- }
-}
-
-#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
-impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
-where
- P: FnMut(I::Item) -> Option<B>,
-{
- type Item = B;
-
- #[inline]
- fn next(&mut self) -> Option<B> {
- let x = self.iter.next()?;
- (self.predicate)(x)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the predicate
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- let Self { iter, predicate } = self;
- iter.try_fold(init, |acc, x| match predicate(x) {
- Some(item) => ControlFlow::from_try(fold(acc, item)),
- None => ControlFlow::Break(try { acc }),
- })
- .into_try()
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
- move |acc, x| Ok(f(acc, x))
- }
-
- self.try_fold(init, ok(fold)).unwrap()
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, B, I: Iterator, P> SourceIter for MapWhile<I, P>
-where
- P: FnMut(I::Item) -> Option<B>,
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<B, I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> where
- P: FnMut(I::Item) -> Option<B>
-{
-}
-
-/// An iterator that skips over `n` elements of `iter`.
-///
-/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`skip`]: Iterator::skip
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Skip<I> {
- iter: I,
- n: usize,
-}
-impl<I> Skip<I> {
- pub(super) fn new(iter: I, n: usize) -> Skip<I> {
- Skip { iter, n }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> Iterator for Skip<I>
-where
- I: Iterator,
-{
- type Item = <I as Iterator>::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- if self.n == 0 {
- self.iter.next()
- } else {
- let old_n = self.n;
- self.n = 0;
- self.iter.nth(old_n)
- }
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<I::Item> {
- // Can't just add n + self.n due to overflow.
- if self.n > 0 {
- let to_skip = self.n;
- self.n = 0;
- // nth(n) skips n+1
- self.iter.nth(to_skip - 1)?;
- }
- self.iter.nth(n)
- }
-
- #[inline]
- fn count(mut self) -> usize {
- if self.n > 0 {
- // nth(n) skips n+1
- if self.iter.nth(self.n - 1).is_none() {
- return 0;
- }
- }
- self.iter.count()
- }
-
- #[inline]
- fn last(mut self) -> Option<I::Item> {
- if self.n > 0 {
- // nth(n) skips n+1
- self.iter.nth(self.n - 1)?;
- }
- self.iter.last()
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (lower, upper) = self.iter.size_hint();
-
- let lower = lower.saturating_sub(self.n);
- let upper = match upper {
- Some(x) => Some(x.saturating_sub(self.n)),
- None => None,
- };
-
- (lower, upper)
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- let n = self.n;
- self.n = 0;
- if n > 0 {
- // nth(n) skips n+1
- if self.iter.nth(n - 1).is_none() {
- return try { init };
- }
- }
- self.iter.try_fold(init, fold)
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- if self.n > 0 {
- // nth(n) skips n+1
- if self.iter.nth(self.n - 1).is_none() {
- return init;
- }
- }
- self.iter.fold(init, fold)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
-
-#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")]
-impl<I> DoubleEndedIterator for Skip<I>
-where
- I: DoubleEndedIterator + ExactSizeIterator,
-{
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.len() > 0 { self.iter.next_back() } else { None }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<I::Item> {
- let len = self.len();
- if n < len {
- self.iter.nth_back(n)
- } else {
- if len > 0 {
- // consume the original iterator
- self.iter.nth_back(len - 1);
- }
- None
- }
- }
-
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- fn check<T, Acc, R: Try<Ok = Acc>>(
- mut n: usize,
- mut fold: impl FnMut(Acc, T) -> R,
- ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
- move |acc, x| {
- n -= 1;
- let r = fold(acc, x);
- if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
- }
- }
-
- let n = self.len();
- if n == 0 { try { init } } else { self.iter.try_rfold(init, check(n, fold)).into_try() }
- }
-
- fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn ok<Acc, T>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, T) -> Result<Acc, !> {
- move |acc, x| Ok(f(acc, x))
- }
-
- self.try_rfold(init, ok(fold)).unwrap()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: Iterator> SourceIter for Skip<I>
-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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {}
-
-/// An iterator that only iterates over the first `n` iterations of `iter`.
-///
-/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`take`]: Iterator::take
-/// [`Iterator`]: trait.Iterator.html
-#[derive(Clone, Debug)]
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Take<I> {
- pub(super) iter: I,
- pub(super) n: usize,
-}
-impl<I> Take<I> {
- pub(super) fn new(iter: I, n: usize) -> Take<I> {
- Take { iter, n }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> Iterator for Take<I>
-where
- I: Iterator,
-{
- type Item = <I as Iterator>::Item;
-
- #[inline]
- fn next(&mut self) -> Option<<I as Iterator>::Item> {
- if self.n != 0 {
- self.n -= 1;
- self.iter.next()
- } else {
- None
- }
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<I::Item> {
- if self.n > n {
- self.n -= n + 1;
- self.iter.nth(n)
- } else {
- if self.n > 0 {
- self.iter.nth(self.n - 1);
- self.n = 0;
- }
- None
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.n == 0 {
- return (0, Some(0));
- }
-
- let (lower, upper) = self.iter.size_hint();
-
- let lower = cmp::min(lower, self.n);
-
- let upper = match upper {
- Some(x) if x < self.n => Some(x),
- _ => Some(self.n),
- };
-
- (lower, upper)
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- fn check<'a, T, Acc, R: Try<Ok = Acc>>(
- n: &'a mut usize,
- mut fold: impl FnMut(Acc, T) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
- move |acc, x| {
- *n -= 1;
- let r = fold(acc, x);
- if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
- }
- }
-
- if self.n == 0 {
- try { init }
- } else {
- let n = &mut self.n;
- self.iter.try_fold(init, check(n, fold)).into_try()
- }
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
- move |acc, x| Ok(f(acc, x))
- }
-
- self.try_fold(init, ok(fold)).unwrap()
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
-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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
-
-#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
-impl<I> DoubleEndedIterator for Take<I>
-where
- I: DoubleEndedIterator + ExactSizeIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<Self::Item> {
- if self.n == 0 {
- None
- } else {
- let n = self.n;
- self.n -= 1;
- self.iter.nth_back(self.iter.len().saturating_sub(n))
- }
- }
-
- #[inline]
- fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
- let len = self.iter.len();
- if self.n > n {
- let m = len.saturating_sub(self.n) + n;
- self.n -= n + 1;
- self.iter.nth_back(m)
- } else {
- if len > 0 {
- self.iter.nth_back(len - 1);
- }
- None
- }
- }
-
- #[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- if self.n == 0 {
- try { init }
- } else {
- let len = self.iter.len();
- if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
- try { init }
- } else {
- self.iter.try_rfold(init, fold)
- }
- }
- }
-
- #[inline]
- fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- if self.n == 0 {
- init
- } else {
- let len = self.iter.len();
- if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
- init
- } else {
- self.iter.rfold(init, fold)
- }
- }
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> FusedIterator for Take<I> where I: FusedIterator {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
-
-/// An iterator to maintain state while iterating another iterator.
-///
-/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`scan`]: Iterator::scan
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct Scan<I, St, F> {
- iter: I,
- f: F,
- state: St,
-}
-impl<I, St, F> Scan<I, St, F> {
- pub(super) fn new(iter: I, state: St, f: F) -> Scan<I, St, F> {
- Scan { iter, state, f }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, St: fmt::Debug, F> fmt::Debug for Scan<I, St, F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Scan").field("iter", &self.iter).field("state", &self.state).finish()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I, St, F> Iterator for Scan<I, St, F>
-where
- I: Iterator,
- F: FnMut(&mut St, I::Item) -> Option<B>,
-{
- type Item = B;
-
- #[inline]
- fn next(&mut self) -> Option<B> {
- let a = self.iter.next()?;
- (self.f)(&mut self.state, a)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.iter.size_hint();
- (0, upper) // can't know a lower bound, due to the scan function
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- fn scan<'a, T, St, B, Acc, R: Try<Ok = Acc>>(
- state: &'a mut St,
- f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
- mut fold: impl FnMut(Acc, B) -> R + 'a,
- ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
- move |acc, x| match f(state, x) {
- None => ControlFlow::Break(try { acc }),
- Some(x) => ControlFlow::from_try(fold(acc, x)),
- }
- }
-
- let state = &mut self.state;
- let f = &mut self.f;
- self.iter.try_fold(init, scan(state, f, fold)).into_try()
- }
-
- #[inline]
- fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- #[inline]
- fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
- move |acc, x| Ok(f(acc, x))
- }
-
- self.try_fold(init, ok(fold)).unwrap()
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
-where
- I: SourceIter<Source = S>,
- F: FnMut(&mut St, I::Item) -> Option<B>,
-{
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> where
- F: FnMut(&mut St, I::Item) -> Option<B>
-{
-}
-
-/// An iterator that calls a function with a reference to each element before
-/// yielding it.
-///
-/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its
-/// documentation for more.
-///
-/// [`inspect`]: Iterator::inspect
-/// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterators are lazy and do nothing unless consumed"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Clone)]
-pub struct Inspect<I, F> {
- iter: I,
- f: F,
-}
-impl<I, F> Inspect<I, F> {
- pub(super) fn new(iter: I, f: F) -> Inspect<I, F> {
- Inspect { iter, f }
- }
-}
-
-#[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Inspect").field("iter", &self.iter).finish()
- }
-}
-
-impl<I: Iterator, F> Inspect<I, F>
-where
- F: FnMut(&I::Item),
-{
- #[inline]
- fn do_inspect(&mut self, elt: Option<I::Item>) -> Option<I::Item> {
- if let Some(ref a) = elt {
- (self.f)(a);
- }
-
- elt
- }
-}
-
-fn inspect_fold<T, Acc>(
- mut f: impl FnMut(&T),
- mut fold: impl FnMut(Acc, T) -> Acc,
-) -> impl FnMut(Acc, T) -> Acc {
- move |acc, item| {
- f(&item);
- fold(acc, item)
- }
-}
-
-fn inspect_try_fold<'a, T, Acc, R>(
- f: &'a mut impl FnMut(&T),
- mut fold: impl FnMut(Acc, T) -> R + 'a,
-) -> impl FnMut(Acc, T) -> R + 'a {
- move |acc, item| {
- f(&item);
- fold(acc, item)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, F> Iterator for Inspect<I, F>
-where
- F: FnMut(&I::Item),
-{
- type Item = I::Item;
-
- #[inline]
- fn next(&mut self) -> Option<I::Item> {
- let next = self.iter.next();
- self.do_inspect(next)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-
- #[inline]
- fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_fold(init, inspect_try_fold(&mut self.f, fold))
- }
-
- #[inline]
- fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.fold(init, inspect_fold(self.f, fold))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
-where
- F: FnMut(&I::Item),
-{
- #[inline]
- fn next_back(&mut self) -> Option<I::Item> {
- let next = self.iter.next_back();
- self.do_inspect(next)
- }
-
- #[inline]
- fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
- where
- Self: Sized,
- Fold: FnMut(Acc, Self::Item) -> R,
- R: Try<Ok = Acc>,
- {
- self.iter.try_rfold(init, inspect_try_fold(&mut self.f, fold))
- }
-
- #[inline]
- fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
- where
- Fold: FnMut(Acc, Self::Item) -> Acc,
- {
- self.iter.rfold(init, inspect_fold(self.f, fold))
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
-where
- F: FnMut(&I::Item),
-{
- fn len(&self) -> usize {
- self.iter.len()
- }
-
- fn is_empty(&self) -> bool {
- self.iter.is_empty()
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F>
-where
- F: FnMut(&I::Item),
- 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) }
- }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {}
-
/// An iterator adapter that produces output as long as the underlying
/// iterator produces `Result::Ok` values.
///
--- /dev/null
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
+use crate::ops::Try;
+
+/// An iterator with a `peek()` that returns an optional reference to the next
+/// element.
+///
+/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`peekable`]: Iterator::peekable
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Peekable<I: Iterator> {
+ iter: I,
+ /// Remember a peeked value, even if it was None.
+ peeked: Option<Option<I::Item>>,
+}
+
+impl<I: Iterator> Peekable<I> {
+ pub(in crate::iter) fn new(iter: I) -> Peekable<I> {
+ Peekable { iter, peeked: None }
+ }
+}
+
+// Peekable must remember if a None has been seen in the `.peek()` method.
+// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the
+// underlying iterator at most once. This does not by itself make the iterator
+// fused.
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator> Iterator for Peekable<I> {
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ match self.peeked.take() {
+ Some(v) => v,
+ None => self.iter.next(),
+ }
+ }
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn count(mut self) -> usize {
+ match self.peeked.take() {
+ Some(None) => 0,
+ Some(Some(_)) => 1 + self.iter.count(),
+ None => self.iter.count(),
+ }
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<I::Item> {
+ match self.peeked.take() {
+ Some(None) => None,
+ Some(v @ Some(_)) if n == 0 => v,
+ Some(Some(_)) => self.iter.nth(n - 1),
+ None => self.iter.nth(n),
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<I::Item> {
+ let peek_opt = match self.peeked.take() {
+ Some(None) => return None,
+ Some(v) => v,
+ None => None,
+ };
+ self.iter.last().or(peek_opt)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let peek_len = match self.peeked {
+ Some(None) => return (0, Some(0)),
+ Some(Some(_)) => 1,
+ None => 0,
+ };
+ let (lo, hi) = self.iter.size_hint();
+ let lo = lo.saturating_add(peek_len);
+ let hi = match hi {
+ Some(x) => x.checked_add(peek_len),
+ None => None,
+ };
+ (lo, hi)
+ }
+
+ #[inline]
+ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ let acc = match self.peeked.take() {
+ Some(None) => return try { init },
+ Some(Some(v)) => f(init, v)?,
+ None => init,
+ };
+ self.iter.try_fold(acc, f)
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let acc = match self.peeked {
+ Some(None) => return init,
+ Some(Some(v)) => fold(init, v),
+ None => init,
+ };
+ self.iter.fold(acc, fold)
+ }
+}
+
+#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Peekable<I>
+where
+ I: DoubleEndedIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ match self.peeked.as_mut() {
+ Some(v @ Some(_)) => self.iter.next_back().or_else(|| v.take()),
+ Some(None) => None,
+ None => self.iter.next_back(),
+ }
+ }
+
+ #[inline]
+ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ match self.peeked.take() {
+ Some(None) => try { init },
+ Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
+ Ok(acc) => f(acc, v),
+ Err(e) => {
+ self.peeked = Some(Some(v));
+ Try::from_error(e)
+ }
+ },
+ None => self.iter.try_rfold(init, f),
+ }
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ match self.peeked {
+ Some(None) => init,
+ Some(Some(v)) => {
+ let acc = self.iter.rfold(init, &mut fold);
+ fold(acc, v)
+ }
+ None => self.iter.rfold(init, fold),
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I: FusedIterator> FusedIterator for Peekable<I> {}
+
+impl<I: Iterator> Peekable<I> {
+ /// Returns a reference to the next() value without advancing the iterator.
+ ///
+ /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`.
+ /// But if the iteration is over, `None` is returned.
+ ///
+ /// [`next`]: Iterator::next
+ ///
+ /// Because `peek()` returns a reference, and many iterators iterate over
+ /// references, there can be a possibly confusing situation where the
+ /// return value is a double reference. You can see this effect in the
+ /// examples below.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let xs = [1, 2, 3];
+ ///
+ /// let mut iter = xs.iter().peekable();
+ ///
+ /// // peek() lets us see into the future
+ /// assert_eq!(iter.peek(), Some(&&1));
+ /// assert_eq!(iter.next(), Some(&1));
+ ///
+ /// assert_eq!(iter.next(), Some(&2));
+ ///
+ /// // The iterator does not advance even if we `peek` multiple times
+ /// assert_eq!(iter.peek(), Some(&&3));
+ /// assert_eq!(iter.peek(), Some(&&3));
+ ///
+ /// assert_eq!(iter.next(), Some(&3));
+ ///
+ /// // After the iterator is finished, so is `peek()`
+ /// assert_eq!(iter.peek(), None);
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn peek(&mut self) -> Option<&I::Item> {
+ let iter = &mut self.iter;
+ self.peeked.get_or_insert_with(|| iter.next()).as_ref()
+ }
+
+ /// Consume and return the next value of this iterator if a condition is true.
+ ///
+ /// If `func` returns `true` for the next value of this iterator, consume and return it.
+ /// Otherwise, return `None`.
+ ///
+ /// # Examples
+ /// Consume a number if it's equal to 0.
+ /// ```
+ /// #![feature(peekable_next_if)]
+ /// let mut iter = (0..5).peekable();
+ /// // The first item of the iterator is 0; consume it.
+ /// assert_eq!(iter.next_if(|&x| x == 0), Some(0));
+ /// // The next item returned is now 1, so `consume` will return `false`.
+ /// assert_eq!(iter.next_if(|&x| x == 0), None);
+ /// // `next_if` saves the value of the next item if it was not equal to `expected`.
+ /// assert_eq!(iter.next(), Some(1));
+ /// ```
+ ///
+ /// Consume any number less than 10.
+ /// ```
+ /// #![feature(peekable_next_if)]
+ /// let mut iter = (1..20).peekable();
+ /// // Consume all numbers less than 10
+ /// while iter.next_if(|&x| x < 10).is_some() {}
+ /// // The next value returned will be 10
+ /// assert_eq!(iter.next(), Some(10));
+ /// ```
+ #[unstable(feature = "peekable_next_if", issue = "72480")]
+ pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> {
+ match self.next() {
+ Some(matched) if func(&matched) => Some(matched),
+ other => {
+ // Since we called `self.next()`, we consumed `self.peeked`.
+ assert!(self.peeked.is_none());
+ self.peeked = Some(other);
+ None
+ }
+ }
+ }
+
+ /// Consume and return the next item if it is equal to `expected`.
+ ///
+ /// # Example
+ /// Consume a number if it's equal to 0.
+ /// ```
+ /// #![feature(peekable_next_if)]
+ /// let mut iter = (0..5).peekable();
+ /// // The first item of the iterator is 0; consume it.
+ /// assert_eq!(iter.next_if_eq(&0), Some(0));
+ /// // The next item returned is now 1, so `consume` will return `false`.
+ /// assert_eq!(iter.next_if_eq(&0), None);
+ /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`.
+ /// assert_eq!(iter.next(), Some(1));
+ /// ```
+ #[unstable(feature = "peekable_next_if", issue = "72480")]
+ pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item>
+ where
+ T: ?Sized,
+ I::Item: PartialEq<T>,
+ {
+ self.next_if(|next| next == expected)
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Peekable<I>
+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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Peekable<I> {}
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::ops::Try;
+
+/// A double-ended iterator with the direction inverted.
+///
+/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`rev`]: Iterator::rev
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Rev<T> {
+ iter: T,
+}
+
+impl<T> Rev<T> {
+ pub(in crate::iter) fn new(iter: T) -> Rev<T> {
+ Rev { iter }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> Iterator for Rev<I>
+where
+ I: DoubleEndedIterator,
+{
+ type Item = <I as Iterator>::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<<I as Iterator>::Item> {
+ self.iter.next_back()
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ #[inline]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ self.iter.advance_back_by(n)
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+ self.iter.nth_back(n)
+ }
+
+ fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.iter.try_rfold(init, f)
+ }
+
+ fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.rfold(init, f)
+ }
+
+ #[inline]
+ fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ self.iter.rfind(predicate)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> DoubleEndedIterator for Rev<I>
+where
+ I: DoubleEndedIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
+ self.iter.next()
+ }
+
+ #[inline]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ self.iter.advance_by(n)
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+ self.iter.nth(n)
+ }
+
+ fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Ok = B>,
+ {
+ self.iter.try_fold(init, f)
+ }
+
+ fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(init, f)
+ }
+
+ fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ self.iter.find(predicate)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ExactSizeIterator for Rev<I>
+where
+ I: ExactSizeIterator + DoubleEndedIterator,
+{
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+
+ fn is_empty(&self) -> bool {
+ self.iter.is_empty()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I> FusedIterator for Rev<I> where I: FusedIterator + DoubleEndedIterator {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, InPlaceIterable};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator to maintain state while iterating another iterator.
+///
+/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`scan`]: Iterator::scan
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct Scan<I, St, F> {
+ iter: I,
+ f: F,
+ state: St,
+}
+
+impl<I, St, F> Scan<I, St, F> {
+ pub(in crate::iter) fn new(iter: I, state: St, f: F) -> Scan<I, St, F> {
+ Scan { iter, state, f }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, St: fmt::Debug, F> fmt::Debug for Scan<I, St, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Scan").field("iter", &self.iter).field("state", &self.state).finish()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<B, I, St, F> Iterator for Scan<I, St, F>
+where
+ I: Iterator,
+ F: FnMut(&mut St, I::Item) -> Option<B>,
+{
+ type Item = B;
+
+ #[inline]
+ fn next(&mut self) -> Option<B> {
+ let a = self.iter.next()?;
+ (self.f)(&mut self.state, a)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the scan function
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ fn scan<'a, T, St, B, Acc, R: Try<Ok = Acc>>(
+ state: &'a mut St,
+ f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
+ mut fold: impl FnMut(Acc, B) -> R + 'a,
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
+ move |acc, x| match f(state, x) {
+ None => ControlFlow::Break(try { acc }),
+ Some(x) => ControlFlow::from_try(fold(acc, x)),
+ }
+ }
+
+ let state = &mut self.state;
+ let f = &mut self.f;
+ self.iter.try_fold(init, scan(state, f, fold)).into_try()
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+ move |acc, x| Ok(f(acc, x))
+ }
+
+ self.try_fold(init, ok(fold)).unwrap()
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F>
+where
+ I: SourceIter<Source = S>,
+ F: FnMut(&mut St, I::Item) -> Option<B>,
+{
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> where
+ F: FnMut(&mut St, I::Item) -> Option<B>
+{
+}
--- /dev/null
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator that skips over `n` elements of `iter`.
+///
+/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`skip`]: Iterator::skip
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Skip<I> {
+ iter: I,
+ n: usize,
+}
+
+impl<I> Skip<I> {
+ pub(in crate::iter) fn new(iter: I, n: usize) -> Skip<I> {
+ Skip { iter, n }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> Iterator for Skip<I>
+where
+ I: Iterator,
+{
+ type Item = <I as Iterator>::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ if self.n == 0 {
+ self.iter.next()
+ } else {
+ let old_n = self.n;
+ self.n = 0;
+ self.iter.nth(old_n)
+ }
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<I::Item> {
+ // Can't just add n + self.n due to overflow.
+ if self.n > 0 {
+ let to_skip = self.n;
+ self.n = 0;
+ // nth(n) skips n+1
+ self.iter.nth(to_skip - 1)?;
+ }
+ self.iter.nth(n)
+ }
+
+ #[inline]
+ fn count(mut self) -> usize {
+ if self.n > 0 {
+ // nth(n) skips n+1
+ if self.iter.nth(self.n - 1).is_none() {
+ return 0;
+ }
+ }
+ self.iter.count()
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<I::Item> {
+ if self.n > 0 {
+ // nth(n) skips n+1
+ self.iter.nth(self.n - 1)?;
+ }
+ self.iter.last()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (lower, upper) = self.iter.size_hint();
+
+ let lower = lower.saturating_sub(self.n);
+ let upper = match upper {
+ Some(x) => Some(x.saturating_sub(self.n)),
+ None => None,
+ };
+
+ (lower, upper)
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ let n = self.n;
+ self.n = 0;
+ if n > 0 {
+ // nth(n) skips n+1
+ if self.iter.nth(n - 1).is_none() {
+ return try { init };
+ }
+ }
+ self.iter.try_fold(init, fold)
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ if self.n > 0 {
+ // nth(n) skips n+1
+ if self.iter.nth(self.n - 1).is_none() {
+ return init;
+ }
+ }
+ self.iter.fold(init, fold)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
+
+#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")]
+impl<I> DoubleEndedIterator for Skip<I>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if self.len() > 0 { self.iter.next_back() } else { None }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<I::Item> {
+ let len = self.len();
+ if n < len {
+ self.iter.nth_back(n)
+ } else {
+ if len > 0 {
+ // consume the original iterator
+ self.iter.nth_back(len - 1);
+ }
+ None
+ }
+ }
+
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ fn check<T, Acc, R: Try<Ok = Acc>>(
+ mut n: usize,
+ mut fold: impl FnMut(Acc, T) -> R,
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
+ move |acc, x| {
+ n -= 1;
+ let r = fold(acc, x);
+ if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
+ }
+ }
+
+ let n = self.len();
+ if n == 0 { try { init } } else { self.iter.try_rfold(init, check(n, fold)).into_try() }
+ }
+
+ fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn ok<Acc, T>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, T) -> Result<Acc, !> {
+ move |acc, x| Ok(f(acc, x))
+ }
+
+ self.try_rfold(init, ok(fold)).unwrap()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Skip<I>
+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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Skip<I> {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::Try;
+
+/// An iterator that rejects elements while `predicate` returns `true`.
+///
+/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`skip_while`]: Iterator::skip_while
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct SkipWhile<I, P> {
+ iter: I,
+ flag: bool,
+ predicate: P,
+}
+
+impl<I, P> SkipWhile<I, P> {
+ pub(in crate::iter) fn new(iter: I, predicate: P) -> SkipWhile<I, P> {
+ SkipWhile { iter, flag: false, predicate }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SkipWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator, P> Iterator for SkipWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ fn check<'a, T>(
+ flag: &'a mut bool,
+ pred: &'a mut impl FnMut(&T) -> bool,
+ ) -> impl FnMut(&T) -> bool + 'a {
+ move |x| {
+ if *flag || !pred(x) {
+ *flag = true;
+ true
+ } else {
+ false
+ }
+ }
+ }
+
+ let flag = &mut self.flag;
+ let pred = &mut self.predicate;
+ self.iter.find(check(flag, pred))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the predicate
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ if !self.flag {
+ match self.next() {
+ Some(v) => init = fold(init, v)?,
+ None => return try { init },
+ }
+ }
+ self.iter.try_fold(init, fold)
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, mut init: Acc, mut fold: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ if !self.flag {
+ match self.next() {
+ Some(v) => init = fold(init, v),
+ None => return init,
+ }
+ }
+ self.iter.fold(init, fold)
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I, P> FusedIterator for SkipWhile<I, P>
+where
+ I: FusedIterator,
+ P: FnMut(&I::Item) -> bool,
+{
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where
+ F: FnMut(&I::Item) -> bool
+{
+}
--- /dev/null
+use crate::{intrinsics, iter::from_fn, ops::Try};
+
+/// An iterator for stepping iterators by a custom amount.
+///
+/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See
+/// its documentation for more.
+///
+/// [`step_by`]: Iterator::step_by
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
+#[derive(Clone, Debug)]
+pub struct StepBy<I> {
+ iter: I,
+ step: usize,
+ first_take: bool,
+}
+
+impl<I> StepBy<I> {
+ pub(in crate::iter) fn new(iter: I, step: usize) -> StepBy<I> {
+ assert!(step != 0);
+ StepBy { iter, step: step - 1, first_take: true }
+ }
+}
+
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
+impl<I> Iterator for StepBy<I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.first_take {
+ self.first_take = false;
+ self.iter.next()
+ } else {
+ self.iter.nth(self.step)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ #[inline]
+ fn first_size(step: usize) -> impl Fn(usize) -> usize {
+ move |n| if n == 0 { 0 } else { 1 + (n - 1) / (step + 1) }
+ }
+
+ #[inline]
+ fn other_size(step: usize) -> impl Fn(usize) -> usize {
+ move |n| n / (step + 1)
+ }
+
+ let (low, high) = self.iter.size_hint();
+
+ if self.first_take {
+ let f = first_size(self.step);
+ (f(low), high.map(f))
+ } else {
+ let f = other_size(self.step);
+ (f(low), high.map(f))
+ }
+ }
+
+ #[inline]
+ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
+ if self.first_take {
+ self.first_take = false;
+ let first = self.iter.next();
+ if n == 0 {
+ return first;
+ }
+ n -= 1;
+ }
+ // n and self.step are indices, we need to add 1 to get the amount of elements
+ // When calling `.nth`, we need to subtract 1 again to convert back to an index
+ // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1`
+ let mut step = self.step + 1;
+ // n + 1 could overflow
+ // thus, if n is usize::MAX, instead of adding one, we call .nth(step)
+ if n == usize::MAX {
+ self.iter.nth(step - 1);
+ } else {
+ n += 1;
+ }
+
+ // overflow handling
+ loop {
+ let mul = n.checked_mul(step);
+ {
+ if intrinsics::likely(mul.is_some()) {
+ return self.iter.nth(mul.unwrap() - 1);
+ }
+ }
+ let div_n = usize::MAX / n;
+ let div_step = usize::MAX / step;
+ let nth_n = div_n * n;
+ let nth_step = div_step * step;
+ let nth = if nth_n > nth_step {
+ step -= div_n;
+ nth_n
+ } else {
+ n -= div_step;
+ nth_step
+ };
+ self.iter.nth(nth - 1);
+ }
+ }
+
+ fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+ where
+ F: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ #[inline]
+ fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
+ move || iter.nth(step)
+ }
+
+ if self.first_take {
+ self.first_take = false;
+ match self.iter.next() {
+ None => return try { acc },
+ Some(x) => acc = f(acc, x)?,
+ }
+ }
+ from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
+ }
+
+ fn fold<Acc, F>(mut self, mut acc: Acc, mut f: F) -> Acc
+ where
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
+ move || iter.nth(step)
+ }
+
+ if self.first_take {
+ self.first_take = false;
+ match self.iter.next() {
+ None => return acc,
+ Some(x) => acc = f(acc, x),
+ }
+ }
+ from_fn(nth(&mut self.iter, self.step)).fold(acc, f)
+ }
+}
+
+impl<I> StepBy<I>
+where
+ I: ExactSizeIterator,
+{
+ // The zero-based index starting from the end of the iterator of the
+ // last element. Used in the `DoubleEndedIterator` implementation.
+ fn next_back_index(&self) -> usize {
+ let rem = self.iter.len() % (self.step + 1);
+ if self.first_take {
+ if rem == 0 { self.step } else { rem - 1 }
+ } else {
+ rem
+ }
+ }
+}
+
+#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for StepBy<I>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.nth_back(self.next_back_index())
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
+ // is out of bounds because the length of `self.iter` does not exceed
+ // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
+ // zero-indexed
+ let n = n.saturating_mul(self.step + 1).saturating_add(self.next_back_index());
+ self.iter.nth_back(n)
+ }
+
+ fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
+ where
+ F: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ #[inline]
+ fn nth_back<I: DoubleEndedIterator>(
+ iter: &mut I,
+ step: usize,
+ ) -> impl FnMut() -> Option<I::Item> + '_ {
+ move || iter.nth_back(step)
+ }
+
+ match self.next_back() {
+ None => try { init },
+ Some(x) => {
+ let acc = f(init, x)?;
+ from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
+ }
+ }
+ }
+
+ #[inline]
+ fn rfold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc
+ where
+ Self: Sized,
+ F: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn nth_back<I: DoubleEndedIterator>(
+ iter: &mut I,
+ step: usize,
+ ) -> impl FnMut() -> Option<I::Item> + '_ {
+ move || iter.nth_back(step)
+ }
+
+ match self.next_back() {
+ None => init,
+ Some(x) => {
+ let acc = f(init, x);
+ from_fn(nth_back(&mut self.iter, self.step)).fold(acc, f)
+ }
+ }
+ }
+}
+
+// StepBy can only make the iterator shorter, so the len will still fit.
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
+impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
--- /dev/null
+use crate::cmp;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator that only iterates over the first `n` iterations of `iter`.
+///
+/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`take`]: Iterator::take
+/// [`Iterator`]: trait.Iterator.html
+#[derive(Clone, Debug)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Take<I> {
+ iter: I,
+ n: usize,
+}
+
+impl<I> Take<I> {
+ pub(in crate::iter) fn new(iter: I, n: usize) -> Take<I> {
+ Take { iter, n }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> Iterator for Take<I>
+where
+ I: Iterator,
+{
+ type Item = <I as Iterator>::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<<I as Iterator>::Item> {
+ if self.n != 0 {
+ self.n -= 1;
+ self.iter.next()
+ } else {
+ None
+ }
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<I::Item> {
+ if self.n > n {
+ self.n -= n + 1;
+ self.iter.nth(n)
+ } else {
+ if self.n > 0 {
+ self.iter.nth(self.n - 1);
+ self.n = 0;
+ }
+ None
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.n == 0 {
+ return (0, Some(0));
+ }
+
+ let (lower, upper) = self.iter.size_hint();
+
+ let lower = cmp::min(lower, self.n);
+
+ let upper = match upper {
+ Some(x) if x < self.n => Some(x),
+ _ => Some(self.n),
+ };
+
+ (lower, upper)
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ fn check<'a, T, Acc, R: Try<Ok = Acc>>(
+ n: &'a mut usize,
+ mut fold: impl FnMut(Acc, T) -> R + 'a,
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
+ move |acc, x| {
+ *n -= 1;
+ let r = fold(acc, x);
+ if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
+ }
+ }
+
+ if self.n == 0 {
+ try { init }
+ } else {
+ let n = &mut self.n;
+ self.iter.try_fold(init, check(n, fold)).into_try()
+ }
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+ move |acc, x| Ok(f(acc, x))
+ }
+
+ self.try_fold(init, ok(fold)).unwrap()
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
+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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}
+
+#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Take<I>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if self.n == 0 {
+ None
+ } else {
+ let n = self.n;
+ self.n -= 1;
+ self.iter.nth_back(self.iter.len().saturating_sub(n))
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ let len = self.iter.len();
+ if self.n > n {
+ let m = len.saturating_sub(self.n) + n;
+ self.n -= n + 1;
+ self.iter.nth_back(m)
+ } else {
+ if len > 0 {
+ self.iter.nth_back(len - 1);
+ }
+ None
+ }
+ }
+
+ #[inline]
+ fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ if self.n == 0 {
+ try { init }
+ } else {
+ let len = self.iter.len();
+ if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
+ try { init }
+ } else {
+ self.iter.try_rfold(init, fold)
+ }
+ }
+ }
+
+ #[inline]
+ fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ if self.n == 0 {
+ init
+ } else {
+ let len = self.iter.len();
+ if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
+ init
+ } else {
+ self.iter.rfold(init, fold)
+ }
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I> FusedIterator for Take<I> where I: FusedIterator {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
--- /dev/null
+use crate::fmt;
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
+use crate::ops::{ControlFlow, Try};
+
+/// An iterator that only accepts elements while `predicate` returns `true`.
+///
+/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
+/// documentation for more.
+///
+/// [`take_while`]: Iterator::take_while
+/// [`Iterator`]: trait.Iterator.html
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
+pub struct TakeWhile<I, P> {
+ iter: I,
+ flag: bool,
+ predicate: P,
+}
+
+impl<I, P> TakeWhile<I, P> {
+ pub(in crate::iter) fn new(iter: I, predicate: P) -> TakeWhile<I, P> {
+ TakeWhile { iter, flag: false, predicate }
+ }
+}
+
+#[stable(feature = "core_impl_debug", since = "1.9.0")]
+impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("TakeWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator, P> Iterator for TakeWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<I::Item> {
+ if self.flag {
+ None
+ } else {
+ let x = self.iter.next()?;
+ if (self.predicate)(&x) {
+ Some(x)
+ } else {
+ self.flag = true;
+ None
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.flag {
+ (0, Some(0))
+ } else {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper) // can't know a lower bound, due to the predicate
+ }
+ }
+
+ #[inline]
+ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> R,
+ R: Try<Ok = Acc>,
+ {
+ fn check<'a, T, Acc, R: Try<Ok = Acc>>(
+ flag: &'a mut bool,
+ p: &'a mut impl FnMut(&T) -> bool,
+ mut fold: impl FnMut(Acc, T) -> R + 'a,
+ ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
+ move |acc, x| {
+ if p(&x) {
+ ControlFlow::from_try(fold(acc, x))
+ } else {
+ *flag = true;
+ ControlFlow::Break(try { acc })
+ }
+ }
+ }
+
+ if self.flag {
+ try { init }
+ } else {
+ let flag = &mut self.flag;
+ let p = &mut self.predicate;
+ self.iter.try_fold(init, check(flag, p, fold)).into_try()
+ }
+ }
+
+ #[inline]
+ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+ where
+ Self: Sized,
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ #[inline]
+ fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+ move |acc, x| Ok(f(acc, x))
+ }
+
+ self.try_fold(init, ok(fold)).unwrap()
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<I, P> FusedIterator for TakeWhile<I, P>
+where
+ I: FusedIterator,
+ P: FnMut(&I::Item) -> bool,
+{
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P>
+where
+ P: FnMut(&I::Item) -> bool,
+ 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) }
+ }
+}
+
+#[unstable(issue = "none", feature = "inplace_iteration")]
+unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where
+ F: FnMut(&I::Item) -> bool
+{
+}
use crate::cmp;
use crate::fmt::{self, Debug};
-
-use super::super::{
- DoubleEndedIterator, ExactSizeIterator, FusedIterator, InPlaceIterable, Iterator, SourceIter,
- TrustedLen,
-};
+use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
+use crate::iter::{InPlaceIterable, SourceIter, TrustedLen};
/// An iterator that iterates two other iterators simultaneously.
///
len: usize,
}
impl<A: Iterator, B: Iterator> Zip<A, B> {
- pub(in super::super) fn new(a: A, b: B) -> Zip<A, B> {
+ pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {
ZipImpl::new(a, b)
}
fn super_nth(&mut self, mut n: usize) -> Option<(A::Item, B::Item)> {
#[stable(feature = "fused", since = "1.26.0")]
pub use self::traits::FusedIterator;
+#[unstable(issue = "none", feature = "inplace_iteration")]
+pub use self::traits::InPlaceIterable;
#[unstable(feature = "trusted_len", issue = "37572")]
pub use self::traits::TrustedLen;
#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::traits::{DoubleEndedIterator, Extend, FromIterator, IntoIterator};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::traits::{ExactSizeIterator, Product, Sum};
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-pub use self::traits::InPlaceIterable;
+pub use self::traits::{
+ DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
+};
#[stable(feature = "iter_cloned", since = "1.1.0")]
pub use self::adapters::Cloned;
pub use self::adapters::Copied;
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::adapters::Flatten;
-
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::adapters::MapWhile;
-#[unstable(issue = "none", feature = "inplace_iteration")]
+#[unstable(feature = "inplace_iteration", issue = "none")]
pub use self::adapters::SourceIter;
#[stable(feature = "iterator_step_by", since = "1.28.0")]
pub use self::adapters::StepBy;
#[unstable(feature = "trusted_random_access", issue = "none")]
pub use self::adapters::TrustedRandomAccess;
#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::adapters::{Chain, Cycle, Enumerate, Filter, FilterMap, Map, Rev, Zip};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::adapters::{FlatMap, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::adapters::{Fuse, Inspect};
+pub use self::adapters::{
+ Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
+ Skip, SkipWhile, Take, TakeWhile, Zip,
+};
pub(crate) use self::adapters::process_results;
-use crate::fmt;
-use crate::marker;
+mod empty;
+mod from_fn;
+mod once;
+mod once_with;
+mod repeat;
+mod repeat_with;
+mod successors;
-use super::{FusedIterator, TrustedLen};
+pub use self::repeat::{repeat, Repeat};
-/// An iterator that repeats an element endlessly.
-///
-/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
-#[derive(Clone, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Repeat<A> {
- element: A,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Clone> Iterator for Repeat<A> {
- type Item = A;
-
- #[inline]
- fn next(&mut self) -> Option<A> {
- Some(self.element.clone())
- }
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- (usize::MAX, None)
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Clone> DoubleEndedIterator for Repeat<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A> {
- Some(self.element.clone())
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<A: Clone> FusedIterator for Repeat<A> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
-
-/// Creates a new iterator that endlessly repeats a single element.
-///
-/// The `repeat()` function repeats a single value over and over again.
-///
-/// Infinite iterators like `repeat()` are often used with adapters like
-/// [`Iterator::take()`], in order to make them finite.
-///
-/// If the element type of the iterator you need does not implement `Clone`,
-/// or if you do not want to keep the repeated element in memory, you can
-/// instead use the [`repeat_with()`] function.
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::iter;
-///
-/// // the number four 4ever:
-/// let mut fours = iter::repeat(4);
-///
-/// assert_eq!(Some(4), fours.next());
-/// assert_eq!(Some(4), fours.next());
-/// assert_eq!(Some(4), fours.next());
-/// assert_eq!(Some(4), fours.next());
-/// assert_eq!(Some(4), fours.next());
-///
-/// // yup, still four
-/// assert_eq!(Some(4), fours.next());
-/// ```
-///
-/// Going finite with [`Iterator::take()`]:
-///
-/// ```
-/// use std::iter;
-///
-/// // that last example was too many fours. Let's only have four fours.
-/// let mut four_fours = iter::repeat(4).take(4);
-///
-/// assert_eq!(Some(4), four_fours.next());
-/// assert_eq!(Some(4), four_fours.next());
-/// assert_eq!(Some(4), four_fours.next());
-/// assert_eq!(Some(4), four_fours.next());
-///
-/// // ... and now we're done
-/// assert_eq!(None, four_fours.next());
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
- Repeat { element: elt }
-}
-
-/// An iterator that repeats elements of type `A` endlessly by
-/// applying the provided closure `F: FnMut() -> A`.
-///
-/// This `struct` is created by the [`repeat_with()`] function.
-/// See its documentation for more.
-#[derive(Copy, Clone, Debug)]
-#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
-pub struct RepeatWith<F> {
- repeater: F,
-}
-
-#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
-impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
- type Item = A;
-
- #[inline]
- fn next(&mut self) -> Option<A> {
- Some((self.repeater)())
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- (usize::MAX, None)
- }
-}
-
-#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
-impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}
-
-/// Creates a new iterator that repeats elements of type `A` endlessly by
-/// applying the provided closure, the repeater, `F: FnMut() -> A`.
-///
-/// The `repeat_with()` function calls the repeater over and over again.
-///
-/// Infinite iterators like `repeat_with()` are often used with adapters like
-/// [`Iterator::take()`], in order to make them finite.
-///
-/// If the element type of the iterator you need implements [`Clone`], and
-/// it is OK to keep the source element in memory, you should instead use
-/// the [`repeat()`] function.
-///
-/// An iterator produced by `repeat_with()` is not a [`DoubleEndedIterator`].
-/// If you need `repeat_with()` to return a [`DoubleEndedIterator`],
-/// please open a GitHub issue explaining your use case.
-///
-/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::iter;
-///
-/// // let's assume we have some value of a type that is not `Clone`
-/// // or which don't want to have in memory just yet because it is expensive:
-/// #[derive(PartialEq, Debug)]
-/// struct Expensive;
-///
-/// // a particular value forever:
-/// let mut things = iter::repeat_with(|| Expensive);
-///
-/// assert_eq!(Some(Expensive), things.next());
-/// assert_eq!(Some(Expensive), things.next());
-/// assert_eq!(Some(Expensive), things.next());
-/// assert_eq!(Some(Expensive), things.next());
-/// assert_eq!(Some(Expensive), things.next());
-/// ```
-///
-/// Using mutation and going finite:
-///
-/// ```rust
-/// use std::iter;
-///
-/// // From the zeroth to the third power of two:
-/// let mut curr = 1;
-/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
-/// .take(4);
-///
-/// assert_eq!(Some(1), pow2.next());
-/// assert_eq!(Some(2), pow2.next());
-/// assert_eq!(Some(4), pow2.next());
-/// assert_eq!(Some(8), pow2.next());
-///
-/// // ... and now we're done
-/// assert_eq!(None, pow2.next());
-/// ```
-#[inline]
-#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
-pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
- RepeatWith { repeater }
-}
-
-/// An iterator that yields nothing.
-///
-/// This `struct` is created by the [`empty()`] function. See its documentation for more.
#[stable(feature = "iter_empty", since = "1.2.0")]
-pub struct Empty<T>(marker::PhantomData<T>);
-
-#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
-unsafe impl<T> Send for Empty<T> {}
-#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
-unsafe impl<T> Sync for Empty<T> {}
+pub use self::empty::{empty, Empty};
-#[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")
- }
-}
-
-#[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Iterator for Empty<T> {
- type Item = T;
-
- fn next(&mut self) -> Option<T> {
- None
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (0, Some(0))
- }
-}
-
-#[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> DoubleEndedIterator for Empty<T> {
- fn next_back(&mut self) -> Option<T> {
- None
- }
-}
-
-#[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> ExactSizeIterator for Empty<T> {
- fn len(&self) -> usize {
- 0
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for Empty<T> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Empty<T> {}
-
-// not #[derive] because that adds a Clone bound on T,
-// which isn't necessary.
-#[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Clone for Empty<T> {
- fn clone(&self) -> Empty<T> {
- Empty(marker::PhantomData)
- }
-}
-
-// not #[derive] because that adds a Default bound on T,
-// which isn't necessary.
-#[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Default for Empty<T> {
- fn default() -> Empty<T> {
- Empty(marker::PhantomData)
- }
-}
-
-/// Creates an iterator that yields nothing.
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::iter;
-///
-/// // this could have been an iterator over i32, but alas, it's just not.
-/// let mut nope = iter::empty::<i32>();
-///
-/// assert_eq!(None, nope.next());
-/// ```
-#[stable(feature = "iter_empty", since = "1.2.0")]
-#[rustc_const_stable(feature = "const_iter_empty", since = "1.32.0")]
-pub const fn empty<T>() -> Empty<T> {
- Empty(marker::PhantomData)
-}
-
-/// An iterator that yields an element exactly once.
-///
-/// This `struct` is created by the [`once()`] function. See its documentation for more.
-#[derive(Clone, Debug)]
#[stable(feature = "iter_once", since = "1.2.0")]
-pub struct Once<T> {
- inner: crate::option::IntoIter<T>,
-}
+pub use self::once::{once, Once};
-#[stable(feature = "iter_once", since = "1.2.0")]
-impl<T> Iterator for Once<T> {
- type Item = T;
-
- fn next(&mut self) -> Option<T> {
- self.inner.next()
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.inner.size_hint()
- }
-}
-
-#[stable(feature = "iter_once", since = "1.2.0")]
-impl<T> DoubleEndedIterator for Once<T> {
- fn next_back(&mut self) -> Option<T> {
- self.inner.next_back()
- }
-}
-
-#[stable(feature = "iter_once", since = "1.2.0")]
-impl<T> ExactSizeIterator for Once<T> {
- fn len(&self) -> usize {
- self.inner.len()
- }
-}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for Once<T> {}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Once<T> {}
-
-/// Creates an iterator that yields an element exactly once.
-///
-/// This is commonly used to adapt a single value into a [`chain()`] of other
-/// kinds of iteration. Maybe you have an iterator that covers almost
-/// everything, but you need an extra special case. Maybe you have a function
-/// which works on iterators, but you only need to process one value.
-///
-/// [`chain()`]: Iterator::chain
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::iter;
-///
-/// // one is the loneliest number
-/// let mut one = iter::once(1);
-///
-/// assert_eq!(Some(1), one.next());
-///
-/// // just one, that's all we get
-/// assert_eq!(None, one.next());
-/// ```
-///
-/// Chaining together with another iterator. Let's say that we want to iterate
-/// over each file of the `.foo` directory, but also a configuration file,
-/// `.foorc`:
-///
-/// ```no_run
-/// use std::iter;
-/// use std::fs;
-/// use std::path::PathBuf;
-///
-/// let dirs = fs::read_dir(".foo").unwrap();
-///
-/// // we need to convert from an iterator of DirEntry-s to an iterator of
-/// // PathBufs, so we use map
-/// let dirs = dirs.map(|file| file.unwrap().path());
-///
-/// // now, our iterator just for our config file
-/// let config = iter::once(PathBuf::from(".foorc"));
-///
-/// // chain the two iterators together into one big iterator
-/// let files = dirs.chain(config);
-///
-/// // this will give us all of the files in .foo as well as .foorc
-/// for f in files {
-/// println!("{:?}", f);
-/// }
-/// ```
-#[stable(feature = "iter_once", since = "1.2.0")]
-pub fn once<T>(value: T) -> Once<T> {
- Once { inner: Some(value).into_iter() }
-}
-
-/// An iterator that yields a single element of type `A` by
-/// applying the provided closure `F: FnOnce() -> A`.
-///
-/// This `struct` is created by the [`once_with()`] function.
-/// See its documentation for more.
-#[derive(Clone, Debug)]
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-pub struct OnceWith<F> {
- gen: Option<F>,
-}
-
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
- type Item = A;
-
- #[inline]
- fn next(&mut self) -> Option<A> {
- let f = self.gen.take()?;
- Some(f())
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.gen.iter().size_hint()
- }
-}
-
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
- fn next_back(&mut self) -> Option<A> {
- self.next()
- }
-}
-
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
- fn len(&self) -> usize {
- self.gen.iter().len()
- }
-}
-
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
-
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
-
-/// Creates an iterator that lazily generates a value exactly once by invoking
-/// the provided closure.
-///
-/// This is commonly used to adapt a single value generator into a [`chain()`] of
-/// other kinds of iteration. Maybe you have an iterator that covers almost
-/// everything, but you need an extra special case. Maybe you have a function
-/// which works on iterators, but you only need to process one value.
-///
-/// Unlike [`once()`], this function will lazily generate the value on request.
-///
-/// [`chain()`]: Iterator::chain
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// use std::iter;
-///
-/// // one is the loneliest number
-/// let mut one = iter::once_with(|| 1);
-///
-/// assert_eq!(Some(1), one.next());
-///
-/// // just one, that's all we get
-/// assert_eq!(None, one.next());
-/// ```
-///
-/// Chaining together with another iterator. Let's say that we want to iterate
-/// over each file of the `.foo` directory, but also a configuration file,
-/// `.foorc`:
-///
-/// ```no_run
-/// use std::iter;
-/// use std::fs;
-/// use std::path::PathBuf;
-///
-/// let dirs = fs::read_dir(".foo").unwrap();
-///
-/// // we need to convert from an iterator of DirEntry-s to an iterator of
-/// // PathBufs, so we use map
-/// let dirs = dirs.map(|file| file.unwrap().path());
-///
-/// // now, our iterator just for our config file
-/// let config = iter::once_with(|| PathBuf::from(".foorc"));
-///
-/// // chain the two iterators together into one big iterator
-/// let files = dirs.chain(config);
-///
-/// // this will give us all of the files in .foo as well as .foorc
-/// for f in files {
-/// println!("{:?}", f);
-/// }
-/// ```
-#[inline]
-#[stable(feature = "iter_once_with", since = "1.43.0")]
-pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
- OnceWith { gen: Some(gen) }
-}
-
-/// Creates a new iterator where each iteration calls the provided closure
-/// `F: FnMut() -> Option<T>`.
-///
-/// This allows creating a custom iterator with any behavior
-/// without using the more verbose syntax of creating a dedicated type
-/// and implementing the [`Iterator`] trait for it.
-///
-/// Note that the `FromFn` iterator doesn’t make assumptions about the behavior of the closure,
-/// and therefore conservatively does not implement [`FusedIterator`],
-/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
-///
-/// The closure can use captures and its environment to track state across iterations. Depending on
-/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
-///
-/// [`move`]: ../../std/keyword.move.html
-///
-/// # Examples
-///
-/// Let’s re-implement the counter iterator from the [module-level documentation]:
-///
-/// [module-level documentation]: super
-///
-/// ```
-/// let mut count = 0;
-/// let counter = std::iter::from_fn(move || {
-/// // Increment our count. This is why we started at zero.
-/// count += 1;
-///
-/// // Check to see if we've finished counting or not.
-/// if count < 6 {
-/// Some(count)
-/// } else {
-/// None
-/// }
-/// });
-/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
-/// ```
-#[inline]
-#[stable(feature = "iter_from_fn", since = "1.34.0")]
-pub fn from_fn<T, F>(f: F) -> FromFn<F>
-where
- F: FnMut() -> Option<T>,
-{
- FromFn(f)
-}
-
-/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
-///
-/// This `struct` is created by the [`iter::from_fn()`] function.
-/// See its documentation for more.
-///
-/// [`iter::from_fn()`]: from_fn
-#[derive(Clone)]
-#[stable(feature = "iter_from_fn", since = "1.34.0")]
-pub struct FromFn<F>(F);
-
-#[stable(feature = "iter_from_fn", since = "1.34.0")]
-impl<T, F> Iterator for FromFn<F>
-where
- F: FnMut() -> Option<T>,
-{
- type Item = T;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- (self.0)()
- }
-}
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+pub use self::repeat_with::{repeat_with, RepeatWith};
#[stable(feature = "iter_from_fn", since = "1.34.0")]
-impl<F> fmt::Debug for FromFn<F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FromFn").finish()
- }
-}
+pub use self::from_fn::{from_fn, FromFn};
-/// Creates a new iterator where each successive item is computed based on the preceding one.
-///
-/// The iterator starts with the given first item (if any)
-/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
-///
-/// ```
-/// use std::iter::successors;
-///
-/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
-/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
-/// ```
#[stable(feature = "iter_successors", since = "1.34.0")]
-pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
-where
- F: FnMut(&T) -> Option<T>,
-{
- // If this function returned `impl Iterator<Item=T>`
- // it could be based on `unfold` and not need a dedicated type.
- // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
- Successors { next: first, succ }
-}
+pub use self::successors::{successors, Successors};
-/// An new iterator where each successive item is computed based on the preceding one.
-///
-/// This `struct` is created by the [`iter::successors()`] function.
-/// See its documentation for more.
-///
-/// [`iter::successors()`]: successors
-#[derive(Clone)]
-#[stable(feature = "iter_successors", since = "1.34.0")]
-pub struct Successors<T, F> {
- next: Option<T>,
- succ: F,
-}
-
-#[stable(feature = "iter_successors", since = "1.34.0")]
-impl<T, F> Iterator for Successors<T, F>
-where
- F: FnMut(&T) -> Option<T>,
-{
- type Item = T;
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- let item = self.next.take()?;
- self.next = (self.succ)(&item);
- Some(item)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- if self.next.is_some() { (1, None) } else { (0, Some(0)) }
- }
-}
-
-#[stable(feature = "iter_successors", since = "1.34.0")]
-impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
-
-#[stable(feature = "iter_successors", since = "1.34.0")]
-impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Successors").field("next", &self.next).finish()
- }
-}
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+pub use self::once_with::{once_with, OnceWith};
--- /dev/null
+use crate::fmt;
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::marker;
+
+/// Creates an iterator that yields nothing.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // this could have been an iterator over i32, but alas, it's just not.
+/// let mut nope = iter::empty::<i32>();
+///
+/// assert_eq!(None, nope.next());
+/// ```
+#[stable(feature = "iter_empty", since = "1.2.0")]
+#[rustc_const_stable(feature = "const_iter_empty", since = "1.32.0")]
+pub const fn empty<T>() -> Empty<T> {
+ Empty(marker::PhantomData)
+}
+
+/// An iterator that yields nothing.
+///
+/// This `struct` is created by the [`empty()`] function. See its documentation for more.
+#[stable(feature = "iter_empty", since = "1.2.0")]
+pub struct Empty<T>(marker::PhantomData<T>);
+
+#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
+unsafe impl<T> Send for Empty<T> {}
+#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
+unsafe impl<T> Sync for Empty<T> {}
+
+#[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")
+ }
+}
+
+#[stable(feature = "iter_empty", since = "1.2.0")]
+impl<T> Iterator for Empty<T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ None
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, Some(0))
+ }
+}
+
+#[stable(feature = "iter_empty", since = "1.2.0")]
+impl<T> DoubleEndedIterator for Empty<T> {
+ fn next_back(&mut self) -> Option<T> {
+ None
+ }
+}
+
+#[stable(feature = "iter_empty", since = "1.2.0")]
+impl<T> ExactSizeIterator for Empty<T> {
+ fn len(&self) -> usize {
+ 0
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for Empty<T> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T> FusedIterator for Empty<T> {}
+
+// not #[derive] because that adds a Clone bound on T,
+// which isn't necessary.
+#[stable(feature = "iter_empty", since = "1.2.0")]
+impl<T> Clone for Empty<T> {
+ fn clone(&self) -> Empty<T> {
+ Empty(marker::PhantomData)
+ }
+}
+
+// not #[derive] because that adds a Default bound on T,
+// which isn't necessary.
+#[stable(feature = "iter_empty", since = "1.2.0")]
+impl<T> Default for Empty<T> {
+ fn default() -> Empty<T> {
+ Empty(marker::PhantomData)
+ }
+}
--- /dev/null
+use crate::fmt;
+
+/// Creates a new iterator where each iteration calls the provided closure
+/// `F: FnMut() -> Option<T>`.
+///
+/// This allows creating a custom iterator with any behavior
+/// without using the more verbose syntax of creating a dedicated type
+/// and implementing the [`Iterator`] trait for it.
+///
+/// Note that the `FromFn` iterator doesn’t make assumptions about the behavior of the closure,
+/// and therefore conservatively does not implement [`FusedIterator`],
+/// or override [`Iterator::size_hint()`] from its default `(0, None)`.
+///
+/// The closure can use captures and its environment to track state across iterations. Depending on
+/// how the iterator is used, this may require specifying the [`move`] keyword on the closure.
+///
+/// [`move`]: ../../std/keyword.move.html
+/// [`FusedIterator`]: crate::iter::FusedIterator
+///
+/// # Examples
+///
+/// Let’s re-implement the counter iterator from [module-level documentation]:
+///
+/// [module-level documentation]: crate::iter
+///
+/// ```
+/// let mut count = 0;
+/// let counter = std::iter::from_fn(move || {
+/// // Increment our count. This is why we started at zero.
+/// count += 1;
+///
+/// // Check to see if we've finished counting or not.
+/// if count < 6 {
+/// Some(count)
+/// } else {
+/// None
+/// }
+/// });
+/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
+/// ```
+#[inline]
+#[stable(feature = "iter_from_fn", since = "1.34.0")]
+pub fn from_fn<T, F>(f: F) -> FromFn<F>
+where
+ F: FnMut() -> Option<T>,
+{
+ FromFn(f)
+}
+
+/// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
+///
+/// This `struct` is created by the [`iter::from_fn()`] function.
+/// See its documentation for more.
+///
+/// [`iter::from_fn()`]: from_fn
+#[derive(Clone)]
+#[stable(feature = "iter_from_fn", since = "1.34.0")]
+pub struct FromFn<F>(F);
+
+#[stable(feature = "iter_from_fn", since = "1.34.0")]
+impl<T, F> Iterator for FromFn<F>
+where
+ F: FnMut() -> Option<T>,
+{
+ type Item = T;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ (self.0)()
+ }
+}
+
+#[stable(feature = "iter_from_fn", since = "1.34.0")]
+impl<F> fmt::Debug for FromFn<F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("FromFn").finish()
+ }
+}
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+
+/// Creates an iterator that yields an element exactly once.
+///
+/// This is commonly used to adapt a single value into a [`chain()`] of other
+/// kinds of iteration. Maybe you have an iterator that covers almost
+/// everything, but you need an extra special case. Maybe you have a function
+/// which works on iterators, but you only need to process one value.
+///
+/// [`chain()`]: Iterator::chain
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // one is the loneliest number
+/// let mut one = iter::once(1);
+///
+/// assert_eq!(Some(1), one.next());
+///
+/// // just one, that's all we get
+/// assert_eq!(None, one.next());
+/// ```
+///
+/// Chaining together with another iterator. Let's say that we want to iterate
+/// over each file of the `.foo` directory, but also a configuration file,
+/// `.foorc`:
+///
+/// ```no_run
+/// use std::iter;
+/// use std::fs;
+/// use std::path::PathBuf;
+///
+/// let dirs = fs::read_dir(".foo").unwrap();
+///
+/// // we need to convert from an iterator of DirEntry-s to an iterator of
+/// // PathBufs, so we use map
+/// let dirs = dirs.map(|file| file.unwrap().path());
+///
+/// // now, our iterator just for our config file
+/// let config = iter::once(PathBuf::from(".foorc"));
+///
+/// // chain the two iterators together into one big iterator
+/// let files = dirs.chain(config);
+///
+/// // this will give us all of the files in .foo as well as .foorc
+/// for f in files {
+/// println!("{:?}", f);
+/// }
+/// ```
+#[stable(feature = "iter_once", since = "1.2.0")]
+pub fn once<T>(value: T) -> Once<T> {
+ Once { inner: Some(value).into_iter() }
+}
+
+/// An iterator that yields an element exactly once.
+///
+/// This `struct` is created by the [`once()`] function. See its documentation for more.
+#[derive(Clone, Debug)]
+#[stable(feature = "iter_once", since = "1.2.0")]
+pub struct Once<T> {
+ inner: crate::option::IntoIter<T>,
+}
+
+#[stable(feature = "iter_once", since = "1.2.0")]
+impl<T> Iterator for Once<T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+#[stable(feature = "iter_once", since = "1.2.0")]
+impl<T> DoubleEndedIterator for Once<T> {
+ fn next_back(&mut self) -> Option<T> {
+ self.inner.next_back()
+ }
+}
+
+#[stable(feature = "iter_once", since = "1.2.0")]
+impl<T> ExactSizeIterator for Once<T> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T> TrustedLen for Once<T> {}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<T> FusedIterator for Once<T> {}
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+
+/// Creates an iterator that lazily generates a value exactly once by invoking
+/// the provided closure.
+///
+/// This is commonly used to adapt a single value generator into a [`chain()`] of
+/// other kinds of iteration. Maybe you have an iterator that covers almost
+/// everything, but you need an extra special case. Maybe you have a function
+/// which works on iterators, but you only need to process one value.
+///
+/// Unlike [`once()`], this function will lazily generate the value on request.
+///
+/// [`chain()`]: Iterator::chain
+/// [`once()`]: crate::iter::once
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // one is the loneliest number
+/// let mut one = iter::once_with(|| 1);
+///
+/// assert_eq!(Some(1), one.next());
+///
+/// // just one, that's all we get
+/// assert_eq!(None, one.next());
+/// ```
+///
+/// Chaining together with another iterator. Let's say that we want to iterate
+/// over each file of the `.foo` directory, but also a configuration file,
+/// `.foorc`:
+///
+/// ```no_run
+/// use std::iter;
+/// use std::fs;
+/// use std::path::PathBuf;
+///
+/// let dirs = fs::read_dir(".foo").unwrap();
+///
+/// // we need to convert from an iterator of DirEntry-s to an iterator of
+/// // PathBufs, so we use map
+/// let dirs = dirs.map(|file| file.unwrap().path());
+///
+/// // now, our iterator just for our config file
+/// let config = iter::once_with(|| PathBuf::from(".foorc"));
+///
+/// // chain the two iterators together into one big iterator
+/// let files = dirs.chain(config);
+///
+/// // this will give us all of the files in .foo as well as .foorc
+/// for f in files {
+/// println!("{:?}", f);
+/// }
+/// ```
+#[inline]
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
+ OnceWith { gen: Some(gen) }
+}
+
+/// An iterator that yields a single element of type `A` by
+/// applying the provided closure `F: FnOnce() -> A`.
+///
+/// This `struct` is created by the [`once_with()`] function.
+/// See its documentation for more.
+#[derive(Clone, Debug)]
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+pub struct OnceWith<F> {
+ gen: Option<F>,
+}
+
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<A> {
+ let f = self.gen.take()?;
+ Some(f())
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.gen.iter().size_hint()
+ }
+}
+
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
+ fn next_back(&mut self) -> Option<A> {
+ self.next()
+ }
+}
+
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
+ fn len(&self) -> usize {
+ self.gen.iter().len()
+ }
+}
+
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
+
+#[stable(feature = "iter_once_with", since = "1.43.0")]
+unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+
+/// Creates a new iterator that endlessly repeats a single element.
+///
+/// The `repeat()` function repeats a single value over and over again.
+///
+/// Infinite iterators like `repeat()` are often used with adapters like
+/// [`Iterator::take()`], in order to make them finite.
+///
+/// If the element type of the iterator you need does not implement `Clone`,
+/// or if you do not want to keep the repeated element in memory, you can
+/// instead use the [`repeat_with()`] function.
+///
+/// [`repeat_with()`]: crate::iter::repeat_with
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // the number four 4ever:
+/// let mut fours = iter::repeat(4);
+///
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+/// assert_eq!(Some(4), fours.next());
+///
+/// // yup, still four
+/// assert_eq!(Some(4), fours.next());
+/// ```
+///
+/// Going finite with [`Iterator::take()`]:
+///
+/// ```
+/// use std::iter;
+///
+/// // that last example was too many fours. Let's only have four fours.
+/// let mut four_fours = iter::repeat(4).take(4);
+///
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+///
+/// // ... and now we're done
+/// assert_eq!(None, four_fours.next());
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
+ Repeat { element: elt }
+}
+
+/// An iterator that repeats an element endlessly.
+///
+/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
+#[derive(Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Repeat<A> {
+ element: A,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Clone> Iterator for Repeat<A> {
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<A> {
+ Some(self.element.clone())
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::MAX, None)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Clone> DoubleEndedIterator for Repeat<A> {
+ #[inline]
+ fn next_back(&mut self) -> Option<A> {
+ Some(self.element.clone())
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<A: Clone> FusedIterator for Repeat<A> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+
+/// Creates a new iterator that repeats elements of type `A` endlessly by
+/// applying the provided closure, the repeater, `F: FnMut() -> A`.
+///
+/// The `repeat_with()` function calls the repeater over and over again.
+///
+/// Infinite iterators like `repeat_with()` are often used with adapters like
+/// [`Iterator::take()`], in order to make them finite.
+///
+/// If the element type of the iterator you need implements [`Clone`], and
+/// it is OK to keep the source element in memory, you should instead use
+/// the [`repeat()`] function.
+///
+/// An iterator produced by `repeat_with()` is not a [`DoubleEndedIterator`].
+/// If you need `repeat_with()` to return a [`DoubleEndedIterator`],
+/// please open a GitHub issue explaining your use case.
+///
+/// [`repeat()`]: crate::iter::repeat
+/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::iter;
+///
+/// // let's assume we have some value of a type that is not `Clone`
+/// // or which don't want to have in memory just yet because it is expensive:
+/// #[derive(PartialEq, Debug)]
+/// struct Expensive;
+///
+/// // a particular value forever:
+/// let mut things = iter::repeat_with(|| Expensive);
+///
+/// assert_eq!(Some(Expensive), things.next());
+/// assert_eq!(Some(Expensive), things.next());
+/// assert_eq!(Some(Expensive), things.next());
+/// assert_eq!(Some(Expensive), things.next());
+/// assert_eq!(Some(Expensive), things.next());
+/// ```
+///
+/// Using mutation and going finite:
+///
+/// ```rust
+/// use std::iter;
+///
+/// // From the zeroth to the third power of two:
+/// let mut curr = 1;
+/// let mut pow2 = iter::repeat_with(|| { let tmp = curr; curr *= 2; tmp })
+/// .take(4);
+///
+/// assert_eq!(Some(1), pow2.next());
+/// assert_eq!(Some(2), pow2.next());
+/// assert_eq!(Some(4), pow2.next());
+/// assert_eq!(Some(8), pow2.next());
+///
+/// // ... and now we're done
+/// assert_eq!(None, pow2.next());
+/// ```
+#[inline]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
+ RepeatWith { repeater }
+}
+
+/// An iterator that repeats elements of type `A` endlessly by
+/// applying the provided closure `F: FnMut() -> A`.
+///
+/// This `struct` is created by the [`repeat_with()`] function.
+/// See its documentation for more.
+#[derive(Copy, Clone, Debug)]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+pub struct RepeatWith<F> {
+ repeater: F,
+}
+
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<A> {
+ Some((self.repeater)())
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::MAX, None)
+ }
+}
+
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A, F: FnMut() -> A> TrustedLen for RepeatWith<F> {}
--- /dev/null
+use crate::{fmt, iter::FusedIterator};
+
+/// Creates a new iterator where each successive item is computed based on the preceding one.
+///
+/// The iterator starts with the given first item (if any)
+/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
+///
+/// ```
+/// use std::iter::successors;
+///
+/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
+/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
+/// ```
+#[stable(feature = "iter_successors", since = "1.34.0")]
+pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
+where
+ F: FnMut(&T) -> Option<T>,
+{
+ // If this function returned `impl Iterator<Item=T>`
+ // it could be based on `unfold` and not need a dedicated type.
+ // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
+ Successors { next: first, succ }
+}
+
+/// An new iterator where each successive item is computed based on the preceding one.
+///
+/// This `struct` is created by the [`iter::successors()`] function.
+/// See its documentation for more.
+///
+/// [`iter::successors()`]: successors
+#[derive(Clone)]
+#[stable(feature = "iter_successors", since = "1.34.0")]
+pub struct Successors<T, F> {
+ next: Option<T>,
+ succ: F,
+}
+
+#[stable(feature = "iter_successors", since = "1.34.0")]
+impl<T, F> Iterator for Successors<T, F>
+where
+ F: FnMut(&T) -> Option<T>,
+{
+ type Item = T;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let item = self.next.take()?;
+ self.next = (self.succ)(&item);
+ Some(item)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.next.is_some() { (1, None) } else { (0, Some(0)) }
+ }
+}
+
+#[stable(feature = "iter_successors", since = "1.34.0")]
+impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
+
+#[stable(feature = "iter_successors", since = "1.34.0")]
+impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Successors").field("next", &self.next).finish()
+ }
+}
/// Required trait for constants used in pattern matches.
///
/// Any type that derives `Eq` automatically implements this trait, *regardless*
-/// of whether its type-parameters implement `Eq`.
+/// of whether its type parameters implement `Eq`.
///
-/// This is a hack to workaround a limitation in our type-system.
+/// This is a hack to work around a limitation in our type system.
///
-/// Background:
+/// # Background
///
/// We want to require that types of consts used in pattern matches
/// have the attribute `#[derive(PartialEq, Eq)]`.
///
/// In a more ideal world, we could check that requirement by just checking that
-/// the given type implements both (1.) the `StructuralPartialEq` trait *and*
-/// (2.) the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
+/// the given type implements both the `StructuralPartialEq` trait *and*
+/// the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
/// and be a case that we want the compiler to accept, and yet the constant's
/// type fails to implement `Eq`.
///
/// ```rust
/// #[derive(PartialEq, Eq)]
/// struct Wrap<X>(X);
+///
/// fn higher_order(_: &()) { }
+///
/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
+///
/// fn main() {
/// match CFN {
/// CFN => {}
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
- /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
+ /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
/// let x_vec = unsafe { &*x.as_ptr() };
/// assert_eq!(x_vec.len(), 3);
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
- /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
+ /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
/// // Create a reference into the `MaybeUninit<Vec<u32>>`.
/// // This is okay because we initialized it.
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
- /// x.write(Some(vec![0,1,2]));
+ /// x.write(Some(vec![0, 1, 2]));
/// let x1 = unsafe { x.assume_init_read() };
/// let x2 = unsafe { x.assume_init_read() };
/// // We now created two copies of the same vector, leading to a double-free ⚠️ when
self.abs_private() < Self::INFINITY
}
+ /// Returns `true` if the number is [subnormal].
+ ///
+ /// ```
+ /// #![feature(is_subnormal)]
+ /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+ /// let max = f32::MAX;
+ /// let lower_than_min = 1.0e-40_f32;
+ /// let zero = 0.0_f32;
+ ///
+ /// assert!(!min.is_subnormal());
+ /// assert!(!max.is_subnormal());
+ ///
+ /// assert!(!zero.is_subnormal());
+ /// assert!(!f32::NAN.is_subnormal());
+ /// assert!(!f32::INFINITY.is_subnormal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(lower_than_min.is_subnormal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+ #[unstable(feature = "is_subnormal", issue = "79288")]
+ #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
+ #[inline]
+ pub const fn is_subnormal(self) -> bool {
+ matches!(self.classify(), FpCategory::Subnormal)
+ }
+
/// Returns `true` if the number is neither zero, infinite,
/// [subnormal], or `NaN`.
///
self.abs_private() < Self::INFINITY
}
+ /// Returns `true` if the number is [subnormal].
+ ///
+ /// ```
+ /// #![feature(is_subnormal)]
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
+ /// let max = f64::MAX;
+ /// let lower_than_min = 1.0e-308_f64;
+ /// let zero = 0.0_f64;
+ ///
+ /// assert!(!min.is_subnormal());
+ /// assert!(!max.is_subnormal());
+ ///
+ /// assert!(!zero.is_subnormal());
+ /// assert!(!f64::NAN.is_subnormal());
+ /// assert!(!f64::INFINITY.is_subnormal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(lower_than_min.is_subnormal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+ #[unstable(feature = "is_subnormal", issue = "79288")]
+ #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
+ #[inline]
+ pub const fn is_subnormal(self) -> bool {
+ matches!(self.classify(), FpCategory::Subnormal)
+ }
+
/// Returns `true` if the number is neither zero, infinite,
/// [subnormal], or `NaN`.
///
/// each can be indexed mutably and immutably.
///
/// ```
-/// use std::ops::{Index,IndexMut};
+/// use std::ops::{Index, IndexMut};
///
/// #[derive(Debug)]
/// enum Side {
// many bytes away from the end of `self`.
// - Any initialized memory is valid `usize`.
unsafe {
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - chunk);
let va = ptr::read_unaligned(pa as *mut usize);
let vb = ptr::read_unaligned(pb as *mut usize);
ptr::write_unaligned(pa as *mut usize, vb.swap_bytes());
// always respected, ensuring the `pb` pointer can be used
// safely.
unsafe {
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - chunk);
let va = ptr::read_unaligned(pa as *mut u32);
let vb = ptr::read_unaligned(pb as *mut u32);
ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16));
// aligned, and can be read from and written to.
unsafe {
// Unsafe swap to avoid the bounds check in safe swap.
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - 1);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - 1);
ptr::swap(pa, pb);
}
i += 1;
/// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
/// (1, 21), (2, 34), (4, 55)];
///
- /// assert_eq!(s.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
- /// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b), Err(7));
- /// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
- /// let r = s.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+ /// assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+ /// assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+ /// let r = s.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
/// buf.fill(1);
/// assert_eq!(buf, vec![1; 10]);
/// ```
+ #[doc(alias = "memset")]
#[unstable(feature = "slice_fill", issue = "70758")]
pub fn fill(&mut self, value: T)
where
/// # Examples
///
/// ```
- /// #![feature(clamp)]
/// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0);
/// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0);
/// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
/// assert!((f32::NAN).clamp(-2.0, 1.0).is_nan());
/// ```
#[must_use = "method returns a new number and does not mutate the original value"]
- #[unstable(feature = "clamp", issue = "44095")]
+ #[stable(feature = "clamp", since = "1.50.0")]
#[inline]
pub fn clamp(self, min: f32, max: f32) -> f32 {
assert!(min <= max);
/// # Examples
///
/// ```
- /// #![feature(clamp)]
/// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0);
/// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0);
/// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
/// assert!((f64::NAN).clamp(-2.0, 1.0).is_nan());
/// ```
#[must_use = "method returns a new number and does not mutate the original value"]
- #[unstable(feature = "clamp", issue = "44095")]
+ #[stable(feature = "clamp", since = "1.50.0")]
#[inline]
pub fn clamp(self, min: f64, max: f64) -> f64 {
assert!(min <= max);
#![feature(cfg_target_thread_local)]
#![feature(char_error_internals)]
#![feature(char_internals)]
-#![feature(clamp)]
#![feature(concat_idents)]
#![feature(const_cstr_unchecked)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(raw)]
#![feature(raw_ref_macros)]
#![feature(ready_macro)]
-#![feature(refcell_take)]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
#![feature(shrink_to)]
var dontApplyBlockRule = toggle.parentNode.parentNode.id !== "main";
if (action === "show") {
removeClass(relatedDoc, "fns-now-collapsed");
- removeClass(docblock, "hidden-by-usual-hider");
+ // Stability information is never hidden.
+ if (hasClass(docblock, "stability") === false) {
+ removeClass(docblock, "hidden-by-usual-hider");
+ }
onEachLazy(toggle.childNodes, adjustToggle(false, dontApplyBlockRule));
onEachLazy(relatedDoc.childNodes, implHider(false, dontApplyBlockRule));
} else if (action === "hide") {
addClass(relatedDoc, "fns-now-collapsed");
- addClass(docblock, "hidden-by-usual-hider");
+ // Stability information should be shown even when detailed info is hidden.
+ if (hasClass(docblock, "stability") === false) {
+ addClass(docblock, "hidden-by-usual-hider");
+ }
onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule));
onEachLazy(relatedDoc.childNodes, implHider(true, dontApplyBlockRule));
}
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
// aux-build:point.rs
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
// revisions:cfail1 cfail2
// compile-flags: -Z query-dep-graph
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![crate_type = "rlib"]
#![feature(rustc_attrs)]
// revisions:cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph --test
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
#![feature(rustc_attrs)]
#![crate_type = "rlib"]
-#![feature(exclusive_range_pattern)]
-
-use std::usize::MAX;
+use std::{isize, usize};
fn main() {
- match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
- 0..=MAX => {}
+ match 0usize {
+ //~^ ERROR non-exhaustive patterns: `_` not covered
+ //~| NOTE pattern `_` not covered
+ //~| NOTE the matched value is of type `usize`
+ //~| NOTE `usize` does not have a fixed maximum value
+ 0..=usize::MAX => {}
}
- match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
- 1..=20 => {}
- -5..3 => {}
+ match 0isize {
+ //~^ ERROR non-exhaustive patterns: `_` not covered
+ //~| NOTE pattern `_` not covered
+ //~| NOTE the matched value is of type `isize`
+ //~| NOTE `isize` does not have a fixed maximum value
+ isize::MIN..=isize::MAX => {}
}
}
error[E0004]: non-exhaustive patterns: `_` not covered
- --> $DIR/feature-gate-precise_pointer_size_matching.rs:6:11
+ --> $DIR/feature-gate-precise_pointer_size_matching.rs:4:11
|
LL | match 0usize {
| ^^^^^^ pattern `_` not covered
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
error[E0004]: non-exhaustive patterns: `_` not covered
- --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
+ --> $DIR/feature-gate-precise_pointer_size_matching.rs:12:11
|
LL | match 0isize {
| ^^^^^^ pattern `_` not covered
+++ /dev/null
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
-#![deny(unreachable_patterns)]
-
-enum IntList {
- Cons(isize, Box<IntList>),
- Nil
-}
-
-fn tail(source_list: &IntList) -> IntList {
- match source_list {
- &IntList::Cons(val, box ref next_list) => tail(next_list),
- &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil),
-//~^ ERROR unreachable pattern
- _ => panic!()
- }
-}
-
-fn main() {}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-12116.rs:15:9
- |
-LL | &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil),
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-12116.rs:5:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-#![deny(unreachable_patterns)]
-
-fn main() {
- let sl = vec![1,2,3];
- let v: isize = match &*sl {
- &[] => 0,
- &[a,b,c] => 3,
- &[a, ref rest @ ..] => a,
- &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern
- };
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-12369.rs:9:9
- |
-LL | &[10,a, ref rest @ ..] => 10
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-12369.rs:1:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-#![allow(overflowing_literals)]
-#![deny(unreachable_patterns)]
-
-fn test(val: u8) {
- match val {
- 256 => print!("0b1110\n"),
- 512 => print!("0b1111\n"),
- //~^ ERROR: unreachable pattern
- _ => print!("fail\n"),
- }
-}
-
-fn main() {
- test(1);
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-13727.rs:7:5
- |
-LL | 512 => print!("0b1111\n"),
- | ^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-13727.rs:2:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-pub enum T {
- T1(()),
- T2(())
-}
-
-pub enum V {
- V1(isize),
- V2(bool)
-}
-
-fn main() {
- match (T::T1(()), V::V2(true)) {
- //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered
- (T::T1(()), V::V1(i)) => (),
- (T::T2(()), V::V2(b)) => ()
- }
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered
- --> $DIR/issue-15129.rs:12:11
- |
-LL | match (T::T1(()), V::V2(true)) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `(T, V)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-fn foo(a: Option<usize>, b: Option<usize>) {
- match (a,b) {
- //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered
- (Some(a), Some(b)) if a == b => { }
- (Some(_), None) |
- (None, Some(_)) => { }
- }
-}
-
-fn main() {
- foo(None, None);
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `(None, None)` not covered
- --> $DIR/issue-2111.rs:2:9
- |
-LL | match (a,b) {
- | ^^^^^ pattern `(None, None)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `(Option<usize>, Option<usize>)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-#![deny(unreachable_patterns)]
-
-fn main() {
- match "world" {
- "hello" => {}
- _ => {},
- }
-
- match "world" {
- ref _x if false => {}
- "hello" => {}
- "hello" => {} //~ ERROR unreachable pattern
- _ => {},
- }
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-30240-b.rs:12:9
- |
-LL | "hello" => {}
- | ^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-30240-b.rs:1:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-// run-pass
-fn main() {
- let &ref a = &[0i32] as &[_];
- assert_eq!(a, &[0i32] as &[_]);
-
- let &ref a = "hello";
- assert_eq!(a, "hello");
-
- match "foo" {
- "fool" => unreachable!(),
- "foo" => {},
- ref _x => unreachable!()
- }
-}
+++ /dev/null
-fn main() {
- match "world" { //~ ERROR non-exhaustive patterns: `&_`
- "hello" => {}
- }
-
- match "world" { //~ ERROR non-exhaustive patterns: `&_`
- ref _x if false => {}
- "hello" => {}
- }
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `&_` not covered
- --> $DIR/issue-30240.rs:2:11
- |
-LL | match "world" {
- | ^^^^^^^ pattern `&_` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `&str`
-
-error[E0004]: non-exhaustive patterns: `&_` not covered
- --> $DIR/issue-30240.rs:6:11
- |
-LL | match "world" {
- | ^^^^^^^ pattern `&_` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `&str`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-fn main() {
- match () { } //~ ERROR non-exhaustive
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: type `()` is non-empty
- --> $DIR/issue-3096-1.rs:2:11
- |
-LL | match () { }
- | ^^
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-enum Bottom { }
-
-fn main() {
- let x = &() as *const () as *const Bottom;
- match x { } //~ ERROR non-exhaustive patterns
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty
- --> $DIR/issue-3096-2.rs:5:11
- |
-LL | match x { }
- | ^
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `*const Bottom`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
LL | .collect();
| ^^^^^^^ method not found in `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6]>>`
|
- ::: $SRC_DIR/core/src/iter/adapters/mod.rs:LL:COL
+ ::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
|
LL | pub struct Cloned<I> {
| -------------------- doesn't satisfy `_: Iterator`
-...
+ |
+ ::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
+ |
LL | pub struct TakeWhile<I, P> {
| -------------------------- doesn't satisfy `<_ as Iterator>::Item = &_`
|
+++ /dev/null
-#![allow(dead_code)]
-#![allow(unused_variables)]
-#![allow(non_snake_case)]
-#![deny(unreachable_patterns)]
-
-#[derive(Clone, Copy)]
-enum Enum {
- Var1,
- Var2,
-}
-
-fn main() {
- use Enum::*;
- let s = Var1;
- match s {
- Var1 => (),
- Var3 => (),
- Var2 => (),
- //~^ ERROR unreachable pattern
- };
- match &s {
- &Var1 => (),
- &Var3 => (),
- &Var2 => (),
- //~^ ERROR unreachable pattern
- };
- let t = (Var1, Var1);
- match t {
- (Var1, b) => (),
- (c, d) => (),
- anything => ()
- //~^ ERROR unreachable pattern
- };
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-31221.rs:18:9
- |
-LL | Var3 => (),
- | ---- matches any value
-LL | Var2 => (),
- | ^^^^ unreachable pattern
- |
-note: the lint level is defined here
- --> $DIR/issue-31221.rs:4:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
- --> $DIR/issue-31221.rs:24:9
- |
-LL | &Var3 => (),
- | ----- matches any value
-LL | &Var2 => (),
- | ^^^^^ unreachable pattern
-
-error: unreachable pattern
- --> $DIR/issue-31221.rs:31:9
- |
-LL | (c, d) => (),
- | ------ matches any value
-LL | anything => ()
- | ^^^^^^^^ unreachable pattern
-
-error: aborting due to 3 previous errors
-
+++ /dev/null
-enum Thing {
- Foo(u8),
- Bar,
- Baz
-}
-
-fn main() {
- let Thing::Foo(y) = Thing::Foo(1);
- //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered
-}
+++ /dev/null
-error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
- --> $DIR/issue-31561.rs:8:9
- |
-LL | / enum Thing {
-LL | | Foo(u8),
-LL | | Bar,
- | | --- not covered
-LL | | Baz
- | | --- not covered
-LL | | }
- | |_- `Thing` defined here
-...
-LL | let Thing::Foo(y) = Thing::Foo(1);
- | ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
- |
- = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
- = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
- = note: the matched value is of type `Thing`
-help: you might want to use `if let` to ignore the variant that isn't matched
- |
-LL | if let Thing::Foo(y) = Thing::Foo(1) { /* */ }
- |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0005`.
+++ /dev/null
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-
-struct HTMLImageData {
- image: Option<String>
-}
-
-struct ElementData {
- kind: Box<ElementKind>
-}
-
-enum ElementKind {
- HTMLImageElement(HTMLImageData)
-}
-
-enum NodeKind {
- Element(ElementData)
-}
-
-struct NodeData {
- kind: Box<NodeKind>,
-}
-
-fn main() {
- let mut id = HTMLImageData { image: None };
- let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) };
- let n = NodeData {kind : box NodeKind::Element(ed)};
- // n.b. span could be better
- match n.kind {
- box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
- box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
- },
- };
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered
- --> $DIR/issue-3601.rs:30:44
- |
-LL | box NodeKind::Element(ed) => match ed.kind {
- | ^^^^^^^ pattern `Box(_, _)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `Box<ElementKind>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-enum Foo {
- Bar { bar: Bar, id: usize }
-}
-
-enum Bar {
- A, B, C, D, E, F
-}
-
-fn test(f: Foo) {
- match f {
- //~^ ERROR non-exhaustive patterns
- //~| patterns
- Foo::Bar { bar: Bar::A, .. } => (),
- Foo::Bar { bar: Bar::B, .. } => (),
- }
-}
-
-fn main() {}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
- --> $DIR/issue-39362.rs:10:11
- |
-LL | / enum Foo {
-LL | | Bar { bar: Bar, id: usize }
-LL | | }
- | |_- `Foo` defined here
-...
-LL | match f {
- | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `Foo`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-fn main() {
- let tup = (true, true);
- println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered
- (false, false) => "foo",
- (false, true) => "bar",
- (true, true) => "baz"
- });
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `(true, false)` not covered
- --> $DIR/issue-4321.rs:3:31
- |
-LL | println!("foo {:}", match tup {
- | ^^^ pattern `(true, false)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `(bool, bool)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-#![crate_type="lib"]
-#![deny(unreachable_patterns)]
-
-mod test_struct {
- // Test the exact copy of the minimal example
- // posted in the issue.
- pub struct Punned {
- foo: [u8; 1],
- bar: [u8; 1],
- }
-
- pub fn test(punned: Punned) {
- match punned {
- Punned { foo: [_], .. } => println!("foo"),
- Punned { bar: [_], .. } => println!("bar"),
- //~^ ERROR unreachable pattern [unreachable_patterns]
- }
- }
-}
-
-mod test_union {
- // Test the same thing using a union.
- pub union Punned {
- foo: [u8; 1],
- bar: [u8; 1],
- }
-
- pub fn test(punned: Punned) {
- match punned {
- Punned { foo: [_] } => println!("foo"),
- Punned { bar: [_] } => println!("bar"),
- //~^ ERROR unreachable pattern [unreachable_patterns]
- }
- }
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/issue-57472.rs:15:13
- |
-LL | Punned { bar: [_], .. } => println!("bar"),
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-57472.rs:2:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
- --> $DIR/issue-57472.rs:31:13
- |
-LL | Punned { bar: [_] } => println!("bar"),
- | ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
--- /dev/null
+// run-pass
+#![feature(const_evaluatable_checked)]
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+trait Foo {}
+
+impl<const N: usize> Foo for [(); N] where Self: FooImpl<{ N == 0 }> {}
+
+trait FooImpl<const IS_ZERO: bool> {}
+
+impl FooImpl<{ 0u8 == 0u8 }> for [(); 0] {}
+
+impl<const N: usize> FooImpl<{ 0u8 != 0u8 }> for [(); N] {}
+
+fn foo<T: Foo>(_v: T) {}
+
+fn main() {
+ foo([]);
+ foo([()]);
+}
+++ /dev/null
-#[derive(PartialEq, Eq)]
-pub struct Tag(pub Context, pub u16);
-
-#[derive(PartialEq, Eq)]
-pub enum Context {
- Tiff,
- Exif,
-}
-
-impl Tag {
- const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665);
-}
-
-fn main() {
- match Tag::ExifIFDPointer {
- //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered
- Tag::ExifIFDPointer => {}
- }
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
- --> $DIR/issue-50900.rs:15:11
- |
-LL | pub struct Tag(pub Context, pub u16);
- | ------------------------------------- `Tag` defined here
-...
-LL | match Tag::ExifIFDPointer {
- | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `Tag`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-#[deny(unreachable_patterns)]
-
-fn parse_data1(data: &[u8]) -> u32 {
- match data {
- b"" => 1,
- _ => 2,
- }
-}
-
-fn parse_data2(data: &[u8]) -> u32 {
- match data { //~ ERROR non-exhaustive patterns: `&[_, ..]` not covered
- b"" => 1,
- }
-}
-
-fn parse_data3(data: &[u8; 0]) -> u8 {
- match data {
- b"" => 1,
- }
-}
-
-fn parse_data4(data: &[u8]) -> u8 {
- match data { //~ ERROR non-exhaustive patterns
- b"aaa" => 0,
- [_, _, _] => 1,
- }
-}
-
-fn parse_data5(data: &[u8; 3]) -> u8 {
- match data {
- b"aaa" => 0,
- [_, _, _] => 1,
- }
-}
-
-fn main() {}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
- --> $DIR/type_polymorphic_byte_str_literals.rs:11:11
- |
-LL | match data {
- | ^^^^ pattern `&[_, ..]` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `&[u8]`
-
-error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
- --> $DIR/type_polymorphic_byte_str_literals.rs:23:11
- |
-LL | match data {
- | ^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `&[u8]`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
| doesn't satisfy `_: FnMut<(&&str,)>`
|
- ::: $SRC_DIR/core/src/iter/adapters/mod.rs:LL:COL
+ ::: $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
|
LL | pub struct Filter<I, P> {
| ----------------------- doesn't satisfy `_: Iterator`
+++ /dev/null
-enum P {
- C(PC),
-}
-
-enum PC {
- Q,
- QA,
-}
-
-fn test(proto: P) {
- match proto { //~ ERROR non-exhaustive patterns
- P::C(PC::Q) => (),
- }
-}
-
-fn main() {}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `C(QA)` not covered
- --> $DIR/issue-40221.rs:11:11
- |
-LL | / enum P {
-LL | | C(PC),
- | | - not covered
-LL | | }
- | |_- `P` defined here
-...
-LL | match proto {
- | ^^^^^ pattern `C(QA)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `P`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-// check-pass
-
-const FOO: &&&u32 = &&&42;
-
-fn main() {
- match unimplemented!() {
- &&&42 => {},
- FOO => {},
- _ => {},
- }
-}
+++ /dev/null
-#![deny(irrefutable_let_patterns)]
-
-fn main() {
- if let _ = 5 {} //~ ERROR irrefutable if-let pattern
-
- while let _ = 5 { //~ ERROR irrefutable while-let pattern
- break;
- }
-}
+++ /dev/null
-error: irrefutable if-let pattern
- --> $DIR/deny-irrefutable-let-patterns.rs:4:5
- |
-LL | if let _ = 5 {}
- | ^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/deny-irrefutable-let-patterns.rs:1:9
- |
-LL | #![deny(irrefutable_let_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: irrefutable while-let pattern
- --> $DIR/deny-irrefutable-let-patterns.rs:6:5
- |
-LL | / while let _ = 5 {
-LL | | break;
-LL | | }
- | |_____^
-
-error: aborting due to 2 previous errors
-
--- /dev/null
+// run-pass
+
+fn main() {
+ let -2147483648..=2147483647 = 1;
+ let 0..=255 = 0u8;
+ let -128..=127 = 0i8;
+ let '\u{0000}'..='\u{10FFFF}' = 'v';
+}
+++ /dev/null
-// run-pass
-
-#![allow(irrefutable_let_patterns)]
-
-fn main() {
- if let _ = 5 {}
-
- while let _ = 5 {
- break;
- }
-}
+++ /dev/null
-// check-pass
-
-#![allow(unreachable_patterns)]
-
-fn main() {
- const CONST: &[Option<()>; 1] = &[Some(())];
- match &[Some(())] {
- &[None] => {}
- CONST => {}
- &[Some(())] => {}
- }
-}
--- /dev/null
+// check-pass
+
+const FOO: &&&u32 = &&&42;
+
+fn main() {
+ match unimplemented!() {
+ &&&42 => {},
+ FOO => {},
+ _ => {},
+ }
+}
--- /dev/null
+#![deny(irrefutable_let_patterns)]
+
+fn main() {
+ if let _ = 5 {} //~ ERROR irrefutable if-let pattern
+
+ while let _ = 5 { //~ ERROR irrefutable while-let pattern
+ break;
+ }
+}
--- /dev/null
+error: irrefutable if-let pattern
+ --> $DIR/deny-irrefutable-let-patterns.rs:4:5
+ |
+LL | if let _ = 5 {}
+ | ^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/deny-irrefutable-let-patterns.rs:1:9
+ |
+LL | #![deny(irrefutable_let_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: irrefutable while-let pattern
+ --> $DIR/deny-irrefutable-let-patterns.rs:6:5
+ |
+LL | / while let _ = 5 {
+LL | | break;
+LL | | }
+ | |_____^
+
+error: aborting due to 2 previous errors
+
+++ /dev/null
-#![feature(precise_pointer_size_matching)]
-#![feature(exclusive_range_pattern)]
-#![deny(unreachable_patterns)]
-#![deny(overlapping_patterns)]
-
-use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};
-
-fn main() {
- let x: u8 = 0;
-
- // A single range covering the entire domain.
- match x {
- 0 ..= 255 => {} // ok
- }
-
- // A combination of ranges and values.
- // These are currently allowed to be overlapping.
- match x {
- 0 ..= 32 => {}
- 33 => {}
- 34 .. 128 => {}
- 100 ..= 200 => {}
- 200 => {} //~ ERROR unreachable pattern
- 201 ..= 255 => {}
- }
-
- // An incomplete set of values.
- match x { //~ ERROR non-exhaustive patterns
- 0 .. 128 => {}
- }
-
- // A more incomplete set of values.
- match x { //~ ERROR non-exhaustive patterns
- 0 ..= 10 => {}
- 20 ..= 30 => {}
- 35 => {}
- 70 .. 255 => {}
- }
-
- let x: i8 = 0;
- match x { //~ ERROR non-exhaustive patterns
- -7 => {}
- -5..=120 => {}
- -2..=20 => {}
- //~^ ERROR unreachable pattern
- 125 => {}
- }
-
- // Let's test other types too!
- let c: char = '\u{0}';
- match c {
- '\u{0}' ..= char::MAX => {} // ok
- }
-
- // We can actually get away with just covering the
- // following two ranges, which correspond to all
- // valid Unicode Scalar Values.
- match c {
- '\u{0000}' ..= '\u{D7FF}' => {}
- '\u{E000}' ..= '\u{10_FFFF}' => {}
- }
-
- match 0u16 {
- 0 ..= u16::MAX => {} // ok
- }
-
- match 0u32 {
- 0 ..= u32::MAX => {} // ok
- }
-
- match 0u64 {
- 0 ..= u64::MAX => {} // ok
- }
-
- match 0u128 {
- 0 ..= u128::MAX => {} // ok
- }
-
- match 0i8 {
- -128 ..= 127 => {} // ok
- }
-
- match 0i8 { //~ ERROR non-exhaustive patterns
- -127 ..= 127 => {}
- }
-
- match 0i16 {
- i16::MIN ..= i16::MAX => {} // ok
- }
-
- match 0i16 { //~ ERROR non-exhaustive patterns
- i16::MIN ..= -1 => {}
- 1 ..= i16::MAX => {}
- }
-
- match 0i32 {
- i32::MIN ..= i32::MAX => {} // ok
- }
-
- match 0i64 {
- i64::MIN ..= i64::MAX => {} // ok
- }
-
- match 0i128 {
- i128::MIN ..= i128::MAX => {} // ok
- }
-
- // Make sure that guards don't factor into the exhaustiveness checks.
- match 0u8 { //~ ERROR non-exhaustive patterns
- 0 .. 128 => {}
- 128 ..= 255 if true => {}
- }
-
- match 0u8 {
- 0 .. 128 => {}
- 128 ..= 255 if false => {}
- 128 ..= 255 => {} // ok, because previous arm was guarded
- }
-
- // Now things start getting a bit more interesting. Testing products!
- match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
- (1, _) => {}
- (_, None) => {}
- }
-
- match (0u8, true) { //~ ERROR non-exhaustive patterns
- (0 ..= 125, false) => {}
- (128 ..= 255, false) => {}
- (0 ..= 255, true) => {}
- }
-
- match (0u8, true) { // ok
- (0 ..= 125, false) => {}
- (128 ..= 255, false) => {}
- (0 ..= 255, true) => {}
- (125 .. 128, false) => {}
- }
-
- match 0u8 {
- 0 .. 2 => {}
- 1 ..= 2 => {} //~ ERROR multiple patterns covering the same range
- _ => {}
- }
-
- const LIM: u128 = u128::MAX - 1;
- match 0u128 { //~ ERROR non-exhaustive patterns
- 0 ..= LIM => {}
- }
-
- match 0u128 { //~ ERROR non-exhaustive patterns
- 0 ..= 4 => {}
- }
-
- match 0u128 { //~ ERROR non-exhaustive patterns
- 4 ..= u128::MAX => {}
- }
-
- const FOO: i32 = 42;
- const BAR: &i32 = &42;
- match &0 {
- &42 => {}
- &FOO => {} //~ ERROR unreachable pattern
- BAR => {} //~ ERROR unreachable pattern
- _ => {}
- }
-
- // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933
- match &0 {
- BAR => {} // ok
- _ => {}
- }
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/exhaustive_integer_patterns.rs:23:9
- |
-LL | 200 => {}
- | ^^^
- |
-note: the lint level is defined here
- --> $DIR/exhaustive_integer_patterns.rs:3:9
- |
-LL | #![deny(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
- --> $DIR/exhaustive_integer_patterns.rs:28:11
- |
-LL | match x {
- | ^ pattern `128_u8..=u8::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u8`
-
-error[E0004]: non-exhaustive patterns: `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more not covered
- --> $DIR/exhaustive_integer_patterns.rs:33:11
- |
-LL | match x {
- | ^ patterns `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u8`
-
-error: unreachable pattern
- --> $DIR/exhaustive_integer_patterns.rs:44:9
- |
-LL | -2..=20 => {}
- | ^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more not covered
- --> $DIR/exhaustive_integer_patterns.rs:41:11
- |
-LL | match x {
- | ^ patterns `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `i8`
-
-error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
- --> $DIR/exhaustive_integer_patterns.rs:83:11
- |
-LL | match 0i8 {
- | ^^^ pattern `i8::MIN` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `i8`
-
-error[E0004]: non-exhaustive patterns: `0_i16` not covered
- --> $DIR/exhaustive_integer_patterns.rs:91:11
- |
-LL | match 0i16 {
- | ^^^^ pattern `0_i16` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `i16`
-
-error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
- --> $DIR/exhaustive_integer_patterns.rs:109:11
- |
-LL | match 0u8 {
- | ^^^ pattern `128_u8..=u8::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u8`
-
-error[E0004]: non-exhaustive patterns: `(0_u8, Some(_))` and `(2_u8..=u8::MAX, Some(_))` not covered
- --> $DIR/exhaustive_integer_patterns.rs:121:11
- |
-LL | match (0u8, Some(())) {
- | ^^^^^^^^^^^^^^^ patterns `(0_u8, Some(_))` and `(2_u8..=u8::MAX, Some(_))` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `(u8, Option<()>)`
-
-error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
- --> $DIR/exhaustive_integer_patterns.rs:126:11
- |
-LL | match (0u8, true) {
- | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `(u8, bool)`
-
-error: multiple patterns covering the same range
- --> $DIR/exhaustive_integer_patterns.rs:141:9
- |
-LL | 0 .. 2 => {}
- | ------ this range overlaps on `1_u8`
-LL | 1 ..= 2 => {}
- | ^^^^^^^ overlapping patterns
- |
-note: the lint level is defined here
- --> $DIR/exhaustive_integer_patterns.rs:4:9
- |
-LL | #![deny(overlapping_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
- --> $DIR/exhaustive_integer_patterns.rs:146:11
- |
-LL | match 0u128 {
- | ^^^^^ pattern `u128::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u128`
-
-error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
- --> $DIR/exhaustive_integer_patterns.rs:150:11
- |
-LL | match 0u128 {
- | ^^^^^ pattern `5_u128..=u128::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u128`
-
-error[E0004]: non-exhaustive patterns: `0_u128..=3_u128` not covered
- --> $DIR/exhaustive_integer_patterns.rs:154:11
- |
-LL | match 0u128 {
- | ^^^^^ pattern `0_u128..=3_u128` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `u128`
-
-error: unreachable pattern
- --> $DIR/exhaustive_integer_patterns.rs:162:9
- |
-LL | &FOO => {}
- | ^^^^
-
-error: unreachable pattern
- --> $DIR/exhaustive_integer_patterns.rs:163:9
- |
-LL | BAR => {}
- | ^^^
-
-error: aborting due to 16 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![allow(illegal_floating_point_literal_pattern)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+ match 0.0 {
+ 0.0..=1.0 => {}
+ _ => {} // ok
+ }
+
+ match 0.0 { //~ ERROR non-exhaustive patterns
+ 0.0..=1.0 => {}
+ }
+
+ match 1.0f64 {
+ 0.01f64 ..= 6.5f64 => {}
+ 0.02f64 => {} //~ ERROR unreachable pattern
+ _ => {}
+ };
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/floats.rs:10:11
+ |
+LL | match 0.0 {
+ | ^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `f64`
+
+error: unreachable pattern
+ --> $DIR/floats.rs:16:7
+ |
+LL | 0.02f64 => {}
+ | ^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/floats.rs:2:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-// run-pass
-
-#![allow(non_snake_case)]
-
-#[derive(Copy, Clone)]
-enum Q { R(Option<usize>) }
-
-fn xyzzy(q: Q) -> usize {
- match q {
- Q::R(S) if S.is_some() => { 0 }
- _ => 1
- }
-}
-
-
-pub fn main() {
- assert_eq!(xyzzy(Q::R(Some(5))), 0);
-}
--- /dev/null
+#![feature(exclusive_range_pattern)]
+#![deny(unreachable_patterns)]
+
+enum Q { R(Option<usize>) }
+
+pub fn main() {
+ match Q::R(None) {
+ Q::R(S) if S.is_some() => {}
+ _ => {}
+ }
+
+ match 0u8 { //~ ERROR non-exhaustive patterns
+ 0 .. 128 => {}
+ 128 ..= 255 if true => {}
+ }
+
+ match 0u8 {
+ 0 .. 128 => {}
+ 128 ..= 255 if false => {}
+ 128 ..= 255 => {} // ok, because previous arm was guarded
+ }
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
+ --> $DIR/guards.rs:12:11
+ |
+LL | match 0u8 {
+ | ^^^ pattern `128_u8..=u8::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u8`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![feature(exclusive_range_pattern)]
+#![feature(assoc_char_consts)]
+#![deny(unreachable_patterns)]
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+macro_rules! test_int {
+ ($s:expr, $min:path, $max:path) => {
+ m!($s, $min..=$max);
+ m!($s, $min..5 | 5..=$max);
+ m!($s, $min..=4 | 5..=$max);
+ m!($s, $min..$max | $max);
+ m!(($s, true), ($min..5, true) | (5..=$max, true) | ($min..=$max, false));
+ }
+}
+
+fn main() {
+ test_int!(0u8, u8::MIN, u8::MAX);
+ test_int!(0u16, u16::MIN, u16::MAX);
+ test_int!(0u32, u32::MIN, u32::MAX);
+ test_int!(0u64, u64::MIN, u64::MAX);
+ test_int!(0u128, u128::MIN, u128::MAX);
+
+ test_int!(0i8, i8::MIN, i8::MAX);
+ test_int!(0i16, i16::MIN, i16::MAX);
+ test_int!(0i32, i32::MIN, i32::MAX);
+ test_int!(0i64, i64::MIN, i64::MAX);
+ test_int!(0i128, i128::MIN, i128::MAX);
+
+ m!('a', '\u{0}'..=char::MAX);
+ m!('a', '\u{0}'..='\u{10_FFFF}');
+ // We can get away with just covering the following two ranges, which correspond to all valid
+ // Unicode Scalar Values.
+ m!('a', '\u{0}'..='\u{D7FF}' | '\u{E000}'..=char::MAX);
+ m!('a', '\u{0}'..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..=char::MAX);
+
+ let 0..=255 = 0u8;
+ let -128..=127 = 0i8;
+ let -2147483648..=2147483647 = 0i32;
+ let '\u{0000}'..='\u{10FFFF}' = 'v';
+
+ // Almost exhaustive
+ m!(0u8, 0..255); //~ ERROR non-exhaustive patterns
+ m!(0u8, 0..=254); //~ ERROR non-exhaustive patterns
+ m!(0u8, 1..=255); //~ ERROR non-exhaustive patterns
+ m!(0u8, 0..42 | 43..=255); //~ ERROR non-exhaustive patterns
+ m!(0i8, -128..127); //~ ERROR non-exhaustive patterns
+ m!(0i8, -128..=126); //~ ERROR non-exhaustive patterns
+ m!(0i8, -127..=127); //~ ERROR non-exhaustive patterns
+ match 0i8 { //~ ERROR non-exhaustive patterns
+ i8::MIN ..= -1 => {}
+ 1 ..= i8::MAX => {}
+ }
+ const ALMOST_MAX: u128 = u128::MAX - 1;
+ m!(0u128, 0..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0u128, 0..=4); //~ ERROR non-exhaustive patterns
+ m!(0u128, 1..=u128::MAX); //~ ERROR non-exhaustive patterns
+
+ // More complicatedly (non-)exhaustive
+ match 0u8 {
+ 0 ..= 30 => {}
+ 20 ..= 70 => {}
+ 50 ..= 255 => {}
+ }
+ match (0u8, true) { //~ ERROR non-exhaustive patterns
+ (0 ..= 125, false) => {}
+ (128 ..= 255, false) => {}
+ (0 ..= 255, true) => {}
+ }
+ match (0u8, true) { // ok
+ (0 ..= 125, false) => {}
+ (128 ..= 255, false) => {}
+ (0 ..= 255, true) => {}
+ (125 .. 128, false) => {}
+ }
+ match (true, 0u8) {
+ (true, 0 ..= 255) => {}
+ (false, 0 ..= 125) => {}
+ (false, 128 ..= 255) => {}
+ (false, 125 .. 128) => {}
+ }
+ match Some(0u8) {
+ None => {}
+ Some(0 ..= 125) => {}
+ Some(128 ..= 255) => {}
+ Some(125 .. 128) => {}
+ }
+ const FOO: u8 = 41;
+ const BAR: &u8 = &42;
+ match &0u8 {
+ 0..41 => {}
+ &FOO => {}
+ BAR => {}
+ 43..=255 => {}
+ }
+
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+ --> $DIR/exhaustiveness.rs:47:8
+ |
+LL | m!(0u8, 0..255);
+ | ^^^ pattern `u8::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+ --> $DIR/exhaustiveness.rs:48:8
+ |
+LL | m!(0u8, 0..=254);
+ | ^^^ pattern `u8::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `0_u8` not covered
+ --> $DIR/exhaustiveness.rs:49:8
+ |
+LL | m!(0u8, 1..=255);
+ | ^^^ pattern `0_u8` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `42_u8` not covered
+ --> $DIR/exhaustiveness.rs:50:8
+ |
+LL | m!(0u8, 0..42 | 43..=255);
+ | ^^^ pattern `42_u8` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+ --> $DIR/exhaustiveness.rs:51:8
+ |
+LL | m!(0i8, -128..127);
+ | ^^^ pattern `i8::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+ --> $DIR/exhaustiveness.rs:52:8
+ |
+LL | m!(0i8, -128..=126);
+ | ^^^ pattern `i8::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
+ --> $DIR/exhaustiveness.rs:53:8
+ |
+LL | m!(0i8, -127..=127);
+ | ^^^ pattern `i8::MIN` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `0_i8` not covered
+ --> $DIR/exhaustiveness.rs:54:11
+ |
+LL | match 0i8 {
+ | ^^^ pattern `0_i8` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
+ --> $DIR/exhaustiveness.rs:59:8
+ |
+LL | m!(0u128, 0..=ALMOST_MAX);
+ | ^^^^^ pattern `u128::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
+ --> $DIR/exhaustiveness.rs:60:8
+ |
+LL | m!(0u128, 0..=4);
+ | ^^^^^ pattern `5_u128..=u128::MAX` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `0_u128` not covered
+ --> $DIR/exhaustiveness.rs:61:8
+ |
+LL | m!(0u128, 1..=u128::MAX);
+ | ^^^^^ pattern `0_u128` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
+ --> $DIR/exhaustiveness.rs:69:11
+ |
+LL | match (0u8, true) {
+ | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(u8, bool)`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![feature(exclusive_range_pattern)]
+#![deny(overlapping_patterns)]
+
+macro_rules! m {
+ ($s:expr, $t1:pat, $t2:pat) => {
+ match $s {
+ $t1 => {}
+ $t2 => {}
+ _ => {}
+ }
+ }
+}
+
+fn main() {
+ m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 20..=30, 31..=40);
+ m!(0u8, 20..=30, 29..=40);
+ m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 20.. 30, 28..=40);
+ m!(0u8, 20.. 30, 30..=40);
+ m!(0u8, 20..=30, 30..=30);
+ m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 20..=30, 29..=30);
+ m!(0u8, 20..=30, 20..=20);
+ m!(0u8, 20..=30, 20..=21);
+ m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 20..=30, 20);
+ m!(0u8, 20..=30, 25);
+ m!(0u8, 20..=30, 30);
+ m!(0u8, 20.. 30, 29);
+ m!(0u8, 20, 20..=30); //~ ERROR multiple patterns covering the same range
+ m!(0u8, 25, 20..=30);
+ m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range
+
+ match (0u8, true) {
+ (0..=10, true) => {}
+ (10..20, true) => {} // not detected
+ (10..20, false) => {}
+ _ => {}
+ }
+ match (true, 0u8) {
+ (true, 0..=10) => {}
+ (true, 10..20) => {} //~ ERROR multiple patterns covering the same range
+ (false, 10..20) => {}
+ _ => {}
+ }
+ match Some(0u8) {
+ Some(0..=10) => {}
+ Some(10..20) => {} //~ ERROR multiple patterns covering the same range
+ _ => {}
+ }
+}
--- /dev/null
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:15:22
+ |
+LL | m!(0u8, 20..=30, 30..=40);
+ | ------- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `30_u8`
+ |
+note: the lint level is defined here
+ --> $DIR/overlapping_range_endpoints.rs:2:9
+ |
+LL | #![deny(overlapping_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:16:22
+ |
+LL | m!(0u8, 30..=40, 20..=30);
+ | ------- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:19:22
+ |
+LL | m!(0u8, 20.. 30, 29..=40);
+ | ------- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `29_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:23:22
+ |
+LL | m!(0u8, 20..=30, 30..=31);
+ | ------- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:27:22
+ |
+LL | m!(0u8, 20..=30, 19..=20);
+ | ------- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `20_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:32:17
+ |
+LL | m!(0u8, 20, 20..=30);
+ | -- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `20_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:34:17
+ |
+LL | m!(0u8, 30, 20..=30);
+ | -- ^^^^^^^ overlapping patterns
+ | |
+ | this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:44:16
+ |
+LL | (true, 0..=10) => {}
+ | ------ this range overlaps on `10_u8`
+LL | (true, 10..20) => {}
+ | ^^^^^^ overlapping patterns
+
+error: multiple patterns covering the same range
+ --> $DIR/overlapping_range_endpoints.rs:50:14
+ |
+LL | Some(0..=10) => {}
+ | ------ this range overlaps on `10_u8`
+LL | Some(10..20) => {}
+ | ^^^^^^ overlapping patterns
+
+error: aborting due to 9 previous errors
+
--- /dev/null
+#![feature(precise_pointer_size_matching)]
+#![feature(exclusive_range_pattern)]
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+fn main() {
+ match 0usize {
+ 0 ..= usize::MAX => {}
+ }
+
+ match 0isize {
+ isize::MIN ..= isize::MAX => {}
+ }
+
+ m!(0usize, 0..=usize::MAX);
+ m!(0usize, 0..5 | 5..=usize::MAX);
+ m!(0usize, 0..usize::MAX | usize::MAX);
+ m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+
+ m!(0isize, isize::MIN..=isize::MAX);
+ m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+ m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+ m!((0isize, true), (isize::MIN..5, true)
+ | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false));
+
+ match 0isize {
+ isize::MIN ..= -1 => {}
+ 0 => {}
+ 1 ..= isize::MAX => {}
+ }
+
+ match 7usize {}
+ //~^ ERROR non-exhaustive patterns
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+ --> $DIR/pointer-sized-int-allow.rs:36:11
+ |
+LL | match 7usize {}
+ | ^^^^^^
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![feature(exclusive_range_pattern)]
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+fn main() {
+ match 0usize {
+ //~^ ERROR non-exhaustive patterns
+ 0 ..= usize::MAX => {}
+ }
+
+ match 0isize {
+ //~^ ERROR non-exhaustive patterns
+ isize::MIN ..= isize::MAX => {}
+ }
+
+ m!(0usize, 0..=usize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!(0usize, 0..5 | 5..=usize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!(0usize, 0..usize::MAX | usize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+ //~^ ERROR non-exhaustive patterns
+
+ m!(0isize, isize::MIN..=isize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+ //~^ ERROR non-exhaustive patterns
+ m!((0isize, true), (isize::MIN..5, true)
+ | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false));
+ //~^^ ERROR non-exhaustive patterns
+
+ match 0isize {
+ //~^ ERROR non-exhaustive patterns
+ isize::MIN ..= -1 => {}
+ 0 => {}
+ 1 ..= isize::MAX => {}
+ }
+
+ match 7usize {}
+ //~^ ERROR non-exhaustive patterns
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:10:11
+ |
+LL | match 0usize {
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+ = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:15:11
+ |
+LL | match 0isize {
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:20:8
+ |
+LL | m!(0usize, 0..=usize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+ = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:22:8
+ |
+LL | m!(0usize, 0..5 | 5..=usize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+ = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:24:8
+ |
+LL | m!(0usize, 0..usize::MAX | usize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+ = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+ --> $DIR/pointer-sized-int-deny.rs:26:8
+ |
+LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+ | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(usize, bool)`
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:29:8
+ |
+LL | m!(0isize, isize::MIN..=isize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:31:8
+ |
+LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:33:8
+ |
+LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+ --> $DIR/pointer-sized-int-deny.rs:35:8
+ |
+LL | m!((0isize, true), (isize::MIN..5, true)
+ | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(isize, bool)`
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/pointer-sized-int-deny.rs:39:11
+ |
+LL | match 0isize {
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+ --> $DIR/pointer-sized-int-deny.rs:46:11
+ |
+LL | match 7usize {}
+ | ^^^^^^
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+// This tests that the lint message explains the reason for the error.
+fn main() {
+ match 0usize {
+ //~^ ERROR non-exhaustive patterns: `_` not covered
+ //~| NOTE pattern `_` not covered
+ //~| NOTE the matched value is of type `usize`
+ //~| NOTE `usize` does not have a fixed maximum value
+ 0..=usize::MAX => {}
+ }
+
+ match 0isize {
+ //~^ ERROR non-exhaustive patterns: `_` not covered
+ //~| NOTE pattern `_` not covered
+ //~| NOTE the matched value is of type `isize`
+ //~| NOTE `isize` does not have a fixed maximum value
+ isize::MIN..=isize::MAX => {}
+ }
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/precise_pointer_matching-message.rs:3:11
+ |
+LL | match 0usize {
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `usize`
+ = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/precise_pointer_matching-message.rs:11:11
+ |
+LL | match 0isize {
+ | ^^^^^^ pattern `_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `isize`
+ = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+ = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![feature(exclusive_range_pattern)]
+#![deny(unreachable_patterns)]
+
+macro_rules! m {
+ ($s:expr, $t1:pat, $t2:pat) => {
+ match $s {
+ $t1 => {}
+ $t2 => {}
+ _ => {}
+ }
+ }
+}
+
+fn main() {
+ m!(0u8, 42, 41);
+ m!(0u8, 42, 42); //~ ERROR unreachable pattern
+ m!(0u8, 42, 43);
+
+ m!(0u8, 20..=30, 19);
+ m!(0u8, 20..=30, 20); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 21); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 25); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 29); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 30); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 31);
+ m!(0u8, 20..30, 19);
+ m!(0u8, 20..30, 20); //~ ERROR unreachable pattern
+ m!(0u8, 20..30, 21); //~ ERROR unreachable pattern
+ m!(0u8, 20..30, 25); //~ ERROR unreachable pattern
+ m!(0u8, 20..30, 29); //~ ERROR unreachable pattern
+ m!(0u8, 20..30, 30);
+ m!(0u8, 20..30, 31);
+
+ m!(0u8, 20..=30, 20..=30); //~ ERROR unreachable pattern
+ m!(0u8, 20.. 30, 20.. 30); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 20.. 30); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 19..=30);
+ m!(0u8, 20..=30, 21..=30); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 20..=29); //~ ERROR unreachable pattern
+ m!(0u8, 20..=30, 20..=31);
+ m!('a', 'A'..='z', 'a'..='z'); //~ ERROR unreachable pattern
+
+ match 0u8 {
+ 5 => {},
+ 6 => {},
+ 7 => {},
+ 8 => {},
+ 5..=8 => {}, //~ ERROR unreachable pattern
+ _ => {},
+ }
+ match 0u8 {
+ 0..10 => {},
+ 10..20 => {},
+ 5..15 => {}, //~ ERROR unreachable pattern
+ _ => {},
+ }
+ match 0u8 {
+ 0..10 => {},
+ 10..20 => {},
+ 20..30 => {},
+ 5..25 => {}, //~ ERROR unreachable pattern
+ _ => {},
+ }
+ match 0u8 {
+ 0..10 => {},
+ 10 => {},
+ 11..=23 => {},
+ 19..30 => {},
+ 5..25 => {}, //~ ERROR unreachable pattern
+ _ => {},
+ }
+ match 0usize {
+ 0..10 => {},
+ 10..20 => {},
+ 5..15 => {}, // FIXME: should be unreachable
+ _ => {},
+ }
+ // Chars between '\u{D7FF}' and '\u{E000}' are invalid even though ranges that contain them are
+ // allowed.
+ match 'a' {
+ _ => {},
+ '\u{D7FF}'..='\u{E000}' => {}, //~ ERROR unreachable pattern
+ }
+ match 'a' {
+ '\u{0}'..='\u{D7FF}' => {},
+ '\u{E000}'..='\u{10_FFFF}' => {},
+ '\u{D7FF}'..='\u{E000}' => {}, // FIXME should be unreachable
+ }
+
+ match (0u8, true) {
+ (0..=255, false) => {}
+ (0..=255, true) => {} // ok
+ }
+ match (true, 0u8) {
+ (false, 0..=255) => {}
+ (true, 0..=255) => {} // ok
+ }
+
+ const FOO: i32 = 42;
+ const BAR: &i32 = &42;
+ match &0 {
+ &42 => {}
+ &FOO => {} //~ ERROR unreachable pattern
+ BAR => {} //~ ERROR unreachable pattern
+ _ => {}
+ }
+ // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933
+ match &0 {
+ BAR => {} // ok
+ _ => {}
+ }
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/reachability.rs:16:17
+ |
+LL | m!(0u8, 42, 42);
+ | ^^
+ |
+note: the lint level is defined here
+ --> $DIR/reachability.rs:2:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:20:22
+ |
+LL | m!(0u8, 20..=30, 20);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:21:22
+ |
+LL | m!(0u8, 20..=30, 21);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:22:22
+ |
+LL | m!(0u8, 20..=30, 25);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:23:22
+ |
+LL | m!(0u8, 20..=30, 29);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:24:22
+ |
+LL | m!(0u8, 20..=30, 30);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:27:21
+ |
+LL | m!(0u8, 20..30, 20);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:28:21
+ |
+LL | m!(0u8, 20..30, 21);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:29:21
+ |
+LL | m!(0u8, 20..30, 25);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:30:21
+ |
+LL | m!(0u8, 20..30, 29);
+ | ^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:34:22
+ |
+LL | m!(0u8, 20..=30, 20..=30);
+ | ^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:35:22
+ |
+LL | m!(0u8, 20.. 30, 20.. 30);
+ | ^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:36:22
+ |
+LL | m!(0u8, 20..=30, 20.. 30);
+ | ^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:38:22
+ |
+LL | m!(0u8, 20..=30, 21..=30);
+ | ^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:39:22
+ |
+LL | m!(0u8, 20..=30, 20..=29);
+ | ^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:41:24
+ |
+LL | m!('a', 'A'..='z', 'a'..='z');
+ | ^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:48:9
+ |
+LL | 5..=8 => {},
+ | ^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:54:9
+ |
+LL | 5..15 => {},
+ | ^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:61:9
+ |
+LL | 5..25 => {},
+ | ^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:69:9
+ |
+LL | 5..25 => {},
+ | ^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:82:9
+ |
+LL | '\u{D7FF}'..='\u{E000}' => {},
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:103:9
+ |
+LL | &FOO => {}
+ | ^^^^
+
+error: unreachable pattern
+ --> $DIR/reachability.rs:104:9
+ |
+LL | BAR => {}
+ | ^^^
+
+error: aborting due to 23 previous errors
+
+++ /dev/null
-// run-pass
-
-fn main() {
- let -2147483648..=2147483647 = 1;
- let 0..=255 = 0u8;
- let -128..=127 = 0i8;
- let '\u{0000}'..='\u{10FFFF}' = 'v';
-}
--- /dev/null
+// run-pass
+
+#![allow(irrefutable_let_patterns)]
+
+fn main() {
+ if let _ = 5 {}
+
+ while let _ = 5 {
+ break;
+ }
+}
--- /dev/null
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![deny(unreachable_patterns)]
+
+enum IntList {
+ Cons(isize, Box<IntList>),
+ Nil
+}
+
+fn tail(source_list: &IntList) -> IntList {
+ match source_list {
+ &IntList::Cons(val, box ref next_list) => tail(next_list),
+ &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil),
+//~^ ERROR unreachable pattern
+ _ => panic!()
+ }
+}
+
+fn main() {}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-12116.rs:15:9
+ |
+LL | &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil),
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-12116.rs:5:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+#![deny(unreachable_patterns)]
+
+fn main() {
+ let sl = vec![1,2,3];
+ let v: isize = match &*sl {
+ &[] => 0,
+ &[a,b,c] => 3,
+ &[a, ref rest @ ..] => a,
+ &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern
+ };
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-12369.rs:9:9
+ |
+LL | &[10,a, ref rest @ ..] => 10
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-12369.rs:1:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+#![allow(overflowing_literals)]
+#![deny(unreachable_patterns)]
+
+fn test(val: u8) {
+ match val {
+ 256 => print!("0b1110\n"),
+ 512 => print!("0b1111\n"),
+ //~^ ERROR: unreachable pattern
+ _ => print!("fail\n"),
+ }
+}
+
+fn main() {
+ test(1);
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-13727.rs:7:5
+ |
+LL | 512 => print!("0b1111\n"),
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-13727.rs:2:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+pub enum T {
+ T1(()),
+ T2(())
+}
+
+pub enum V {
+ V1(isize),
+ V2(bool)
+}
+
+fn main() {
+ match (T::T1(()), V::V2(true)) {
+ //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered
+ (T::T1(()), V::V1(i)) => (),
+ (T::T2(()), V::V2(b)) => ()
+ }
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered
+ --> $DIR/issue-15129.rs:12:11
+ |
+LL | match (T::T1(()), V::V2(true)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(T, V)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+fn foo(a: Option<usize>, b: Option<usize>) {
+ match (a,b) {
+ //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered
+ (Some(a), Some(b)) if a == b => { }
+ (Some(_), None) |
+ (None, Some(_)) => { }
+ }
+}
+
+fn main() {
+ foo(None, None);
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `(None, None)` not covered
+ --> $DIR/issue-2111.rs:2:9
+ |
+LL | match (a,b) {
+ | ^^^^^ pattern `(None, None)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(Option<usize>, Option<usize>)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![deny(unreachable_patterns)]
+
+fn main() {
+ match "world" {
+ "hello" => {}
+ _ => {},
+ }
+
+ match "world" {
+ ref _x if false => {}
+ "hello" => {}
+ "hello" => {} //~ ERROR unreachable pattern
+ _ => {},
+ }
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-30240-b.rs:12:9
+ |
+LL | "hello" => {}
+ | ^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-30240-b.rs:1:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+// run-pass
+fn main() {
+ let &ref a = &[0i32] as &[_];
+ assert_eq!(a, &[0i32] as &[_]);
+
+ let &ref a = "hello";
+ assert_eq!(a, "hello");
+
+ match "foo" {
+ "fool" => unreachable!(),
+ "foo" => {},
+ ref _x => unreachable!()
+ }
+}
--- /dev/null
+fn main() {
+ match "world" { //~ ERROR non-exhaustive patterns: `&_`
+ "hello" => {}
+ }
+
+ match "world" { //~ ERROR non-exhaustive patterns: `&_`
+ ref _x if false => {}
+ "hello" => {}
+ }
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `&_` not covered
+ --> $DIR/issue-30240.rs:2:11
+ |
+LL | match "world" {
+ | ^^^^^^^ pattern `&_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `&str`
+
+error[E0004]: non-exhaustive patterns: `&_` not covered
+ --> $DIR/issue-30240.rs:6:11
+ |
+LL | match "world" {
+ | ^^^^^^^ pattern `&_` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `&str`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+fn main() {
+ match () { } //~ ERROR non-exhaustive
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: type `()` is non-empty
+ --> $DIR/issue-3096-1.rs:2:11
+ |
+LL | match () { }
+ | ^^
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+enum Bottom { }
+
+fn main() {
+ let x = &() as *const () as *const Bottom;
+ match x { } //~ ERROR non-exhaustive patterns
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty
+ --> $DIR/issue-3096-2.rs:5:11
+ |
+LL | match x { }
+ | ^
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `*const Bottom`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(non_snake_case)]
+#![deny(unreachable_patterns)]
+
+#[derive(Clone, Copy)]
+enum Enum {
+ Var1,
+ Var2,
+}
+
+fn main() {
+ use Enum::*;
+ let s = Var1;
+ match s {
+ Var1 => (),
+ Var3 => (),
+ Var2 => (),
+ //~^ ERROR unreachable pattern
+ };
+ match &s {
+ &Var1 => (),
+ &Var3 => (),
+ &Var2 => (),
+ //~^ ERROR unreachable pattern
+ };
+ let t = (Var1, Var1);
+ match t {
+ (Var1, b) => (),
+ (c, d) => (),
+ anything => ()
+ //~^ ERROR unreachable pattern
+ };
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-31221.rs:18:9
+ |
+LL | Var3 => (),
+ | ---- matches any value
+LL | Var2 => (),
+ | ^^^^ unreachable pattern
+ |
+note: the lint level is defined here
+ --> $DIR/issue-31221.rs:4:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/issue-31221.rs:24:9
+ |
+LL | &Var3 => (),
+ | ----- matches any value
+LL | &Var2 => (),
+ | ^^^^^ unreachable pattern
+
+error: unreachable pattern
+ --> $DIR/issue-31221.rs:31:9
+ |
+LL | (c, d) => (),
+ | ------ matches any value
+LL | anything => ()
+ | ^^^^^^^^ unreachable pattern
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+enum Thing {
+ Foo(u8),
+ Bar,
+ Baz
+}
+
+fn main() {
+ let Thing::Foo(y) = Thing::Foo(1);
+ //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered
+}
--- /dev/null
+error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
+ --> $DIR/issue-31561.rs:8:9
+ |
+LL | / enum Thing {
+LL | | Foo(u8),
+LL | | Bar,
+ | | --- not covered
+LL | | Baz
+ | | --- not covered
+LL | | }
+ | |_- `Thing` defined here
+...
+LL | let Thing::Foo(y) = Thing::Foo(1);
+ | ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
+ |
+ = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+ = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+ = note: the matched value is of type `Thing`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let Thing::Foo(y) = Thing::Foo(1) { /* */ }
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0005`.
--- /dev/null
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+
+struct HTMLImageData {
+ image: Option<String>
+}
+
+struct ElementData {
+ kind: Box<ElementKind>
+}
+
+enum ElementKind {
+ HTMLImageElement(HTMLImageData)
+}
+
+enum NodeKind {
+ Element(ElementData)
+}
+
+struct NodeData {
+ kind: Box<NodeKind>,
+}
+
+fn main() {
+ let mut id = HTMLImageData { image: None };
+ let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) };
+ let n = NodeData {kind : box NodeKind::Element(ed)};
+ // n.b. span could be better
+ match n.kind {
+ box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
+ box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
+ },
+ };
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered
+ --> $DIR/issue-3601.rs:30:44
+ |
+LL | box NodeKind::Element(ed) => match ed.kind {
+ | ^^^^^^^ pattern `Box(_, _)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `Box<ElementKind>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+enum Foo {
+ Bar { bar: Bar, id: usize }
+}
+
+enum Bar {
+ A, B, C, D, E, F
+}
+
+fn test(f: Foo) {
+ match f {
+ //~^ ERROR non-exhaustive patterns
+ //~| patterns
+ Foo::Bar { bar: Bar::A, .. } => (),
+ Foo::Bar { bar: Bar::B, .. } => (),
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+ --> $DIR/issue-39362.rs:10:11
+ |
+LL | / enum Foo {
+LL | | Bar { bar: Bar, id: usize }
+LL | | }
+ | |_- `Foo` defined here
+...
+LL | match f {
+ | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+enum P {
+ C(PC),
+}
+
+enum PC {
+ Q,
+ QA,
+}
+
+fn test(proto: P) {
+ match proto { //~ ERROR non-exhaustive patterns
+ P::C(PC::Q) => (),
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `C(QA)` not covered
+ --> $DIR/issue-40221.rs:11:11
+ |
+LL | / enum P {
+LL | | C(PC),
+ | | - not covered
+LL | | }
+ | |_- `P` defined here
+...
+LL | match proto {
+ | ^^^^^ pattern `C(QA)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `P`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+fn main() {
+ let tup = (true, true);
+ println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered
+ (false, false) => "foo",
+ (false, true) => "bar",
+ (true, true) => "baz"
+ });
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `(true, false)` not covered
+ --> $DIR/issue-4321.rs:3:31
+ |
+LL | println!("foo {:}", match tup {
+ | ^^^ pattern `(true, false)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `(bool, bool)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-// check-pass
-#![feature(exclusive_range_pattern)]
-#![warn(unreachable_patterns)]
-#![warn(overlapping_patterns)]
-
-fn main() {
- // These cases should generate no warning.
- match 10 {
- 1..10 => {},
- 10 => {},
- _ => {},
- }
-
- match 10 {
- 1..10 => {},
- 9..=10 => {}, //~ WARNING multiple patterns covering the same range
- _ => {},
- }
-
- match 10 {
- 1..10 => {},
- 10..=10 => {},
- _ => {},
- }
-
- // These cases should generate "unreachable pattern" warnings.
- match 10 {
- 1..10 => {},
- 9 => {}, //~ WARNING unreachable pattern
- _ => {},
- }
-
- match 10 {
- 1..10 => {},
- 8..=9 => {}, //~ WARNING unreachable pattern
- _ => {},
- }
-
- match 10 {
- 5..7 => {},
- 6 => {}, //~ WARNING unreachable pattern
- 1..10 => {},
- 9..=9 => {}, //~ WARNING unreachable pattern
- 6 => {}, //~ WARNING unreachable pattern
- _ => {},
- }
-}
+++ /dev/null
-warning: multiple patterns covering the same range
- --> $DIR/issue-43253.rs:16:9
- |
-LL | 1..10 => {},
- | ----- this range overlaps on `9_i32`
-LL | 9..=10 => {},
- | ^^^^^^ overlapping patterns
- |
-note: the lint level is defined here
- --> $DIR/issue-43253.rs:4:9
- |
-LL | #![warn(overlapping_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
- --> $DIR/issue-43253.rs:29:9
- |
-LL | 9 => {},
- | ^
- |
-note: the lint level is defined here
- --> $DIR/issue-43253.rs:3:9
- |
-LL | #![warn(unreachable_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
- --> $DIR/issue-43253.rs:35:9
- |
-LL | 8..=9 => {},
- | ^^^^^
-
-warning: unreachable pattern
- --> $DIR/issue-43253.rs:41:9
- |
-LL | 6 => {},
- | ^
-
-warning: unreachable pattern
- --> $DIR/issue-43253.rs:43:9
- |
-LL | 9..=9 => {},
- | ^^^^^
-
-warning: unreachable pattern
- --> $DIR/issue-43253.rs:44:9
- |
-LL | 6 => {},
- | ^
-
-warning: 6 warnings emitted
-
--- /dev/null
+#[derive(PartialEq, Eq)]
+pub struct Tag(pub Context, pub u16);
+
+#[derive(PartialEq, Eq)]
+pub enum Context {
+ Tiff,
+ Exif,
+}
+
+impl Tag {
+ const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665);
+}
+
+fn main() {
+ match Tag::ExifIFDPointer {
+ //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered
+ Tag::ExifIFDPointer => {}
+ }
+}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
+ --> $DIR/issue-50900.rs:15:11
+ |
+LL | pub struct Tag(pub Context, pub u16);
+ | ------------------------------------- `Tag` defined here
+...
+LL | match Tag::ExifIFDPointer {
+ | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `Tag`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#![crate_type="lib"]
+#![deny(unreachable_patterns)]
+
+mod test_struct {
+ // Test the exact copy of the minimal example
+ // posted in the issue.
+ pub struct Punned {
+ foo: [u8; 1],
+ bar: [u8; 1],
+ }
+
+ pub fn test(punned: Punned) {
+ match punned {
+ Punned { foo: [_], .. } => println!("foo"),
+ Punned { bar: [_], .. } => println!("bar"),
+ //~^ ERROR unreachable pattern [unreachable_patterns]
+ }
+ }
+}
+
+mod test_union {
+ // Test the same thing using a union.
+ pub union Punned {
+ foo: [u8; 1],
+ bar: [u8; 1],
+ }
+
+ pub fn test(punned: Punned) {
+ match punned {
+ Punned { foo: [_] } => println!("foo"),
+ Punned { bar: [_] } => println!("bar"),
+ //~^ ERROR unreachable pattern [unreachable_patterns]
+ }
+ }
+}
--- /dev/null
+error: unreachable pattern
+ --> $DIR/issue-57472.rs:15:13
+ |
+LL | Punned { bar: [_], .. } => println!("bar"),
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-57472.rs:2:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/issue-57472.rs:31:13
+ |
+LL | Punned { bar: [_] } => println!("bar"),
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+// check-pass
+
+#![allow(unreachable_patterns)]
+
+fn main() {
+ const CONST: &[Option<()>; 1] = &[Some(())];
+ match &[Some(())] {
+ &[None] => {}
+ CONST => {}
+ &[Some(())] => {}
+ }
+}
+++ /dev/null
-#![deny(unreachable_patterns, overlapping_patterns)]
-
-fn main() {
- match 5 {
- 1 ..= 10 => { }
- 5 ..= 6 => { }
- //~^ ERROR unreachable pattern
- _ => {}
- };
-
- match 5 {
- 3 ..= 6 => { }
- 4 ..= 6 => { }
- //~^ ERROR unreachable pattern
- _ => {}
- };
-
- match 5 {
- 4 ..= 6 => { }
- 4 ..= 6 => { }
- //~^ ERROR unreachable pattern
- _ => {}
- };
-
- match 'c' {
- 'A' ..= 'z' => {}
- 'a' ..= 'z' => {}
- //~^ ERROR unreachable pattern
- _ => {}
- };
-
- match 1.0f64 {
- 0.01f64 ..= 6.5f64 => {}
- //~^ WARNING floating-point types cannot be used in patterns
- //~| WARNING floating-point types cannot be used in patterns
- //~| WARNING floating-point types cannot be used in patterns
- //~| WARNING floating-point types cannot be used in patterns
- //~| WARNING this was previously accepted by the compiler
- //~| WARNING this was previously accepted by the compiler
- //~| WARNING this was previously accepted by the compiler
- //~| WARNING this was previously accepted by the compiler
- 0.02f64 => {} //~ ERROR unreachable pattern
- //~^ WARNING floating-point types cannot be used in patterns
- //~| WARNING floating-point types cannot be used in patterns
- //~| WARNING this was previously accepted by the compiler
- //~| WARNING this was previously accepted by the compiler
- _ => {}
- };
-}
+++ /dev/null
-error: unreachable pattern
- --> $DIR/match-range-fail-dominate.rs:6:7
- |
-LL | 5 ..= 6 => { }
- | ^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/match-range-fail-dominate.rs:1:9
- |
-LL | #![deny(unreachable_patterns, overlapping_patterns)]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
- --> $DIR/match-range-fail-dominate.rs:13:7
- |
-LL | 4 ..= 6 => { }
- | ^^^^^^^
-
-error: unreachable pattern
- --> $DIR/match-range-fail-dominate.rs:20:7
- |
-LL | 4 ..= 6 => { }
- | ^^^^^^^
-
-error: unreachable pattern
- --> $DIR/match-range-fail-dominate.rs:27:7
- |
-LL | 'a' ..= 'z' => {}
- | ^^^^^^^^^^^
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:33:7
- |
-LL | 0.01f64 ..= 6.5f64 => {}
- | ^^^^^^^
- |
- = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:33:19
- |
-LL | 0.01f64 ..= 6.5f64 => {}
- | ^^^^^^
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:42:7
- |
-LL | 0.02f64 => {}
- | ^^^^^^^
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: unreachable pattern
- --> $DIR/match-range-fail-dominate.rs:42:7
- |
-LL | 0.02f64 => {}
- | ^^^^^^^
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:33:7
- |
-LL | 0.01f64 ..= 6.5f64 => {}
- | ^^^^^^^
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:33:19
- |
-LL | 0.01f64 ..= 6.5f64 => {}
- | ^^^^^^
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
- --> $DIR/match-range-fail-dominate.rs:42:7
- |
-LL | 0.02f64 => {}
- | ^^^^^^^
- |
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: aborting due to 5 previous errors; 6 warnings emitted
-
+++ /dev/null
-#![allow(illegal_floating_point_literal_pattern)]
-#![deny(unreachable_patterns)]
-
-fn main() {
- match 0.0 {
- 0.0..=1.0 => {}
- _ => {} // ok
- }
-
- match 0.0 { //~ ERROR non-exhaustive patterns
- 0.0..=1.0 => {}
- }
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `_` not covered
- --> $DIR/non-exhaustive-float-range-match.rs:10:11
- |
-LL | match 0.0 {
- | ^^^ pattern `_` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `f64`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-use std::{usize, isize};
-
-fn main() {
- match 0usize {
- //~^ ERROR non-exhaustive patterns
- //~| NOTE pattern `_` not covered
- //~| NOTE the matched value is of type `usize`
- //~| NOTE `usize` does not have a fixed maximum value
- 0 ..= usize::MAX => {}
- }
-
- match 0isize {
- //~^ ERROR non-exhaustive patterns
- //~| NOTE pattern `_` not covered
- //~| NOTE the matched value is of type `isize`
- //~| NOTE `isize` does not have a fixed maximum value
- isize::MIN ..= isize::MAX => {}
- }
-
- match 7usize {}
- //~^ ERROR non-exhaustive patterns
- //~| NOTE the matched value is of type `usize`
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `_` not covered
- --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:4:11
- |
-LL | match 0usize {
- | ^^^^^^ pattern `_` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `usize`
- = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
- = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
-
-error[E0004]: non-exhaustive patterns: `_` not covered
- --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:12:11
- |
-LL | match 0isize {
- | ^^^^^^ pattern `_` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `isize`
- = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
- = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
-
-error[E0004]: non-exhaustive patterns: type `usize` is non-empty
- --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:20:11
- |
-LL | match 7usize {}
- | ^^^^^^
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `usize`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
--- /dev/null
+#[deny(unreachable_patterns)]
+
+fn parse_data1(data: &[u8]) -> u32 {
+ match data {
+ b"" => 1,
+ _ => 2,
+ }
+}
+
+fn parse_data2(data: &[u8]) -> u32 {
+ match data { //~ ERROR non-exhaustive patterns: `&[_, ..]` not covered
+ b"" => 1,
+ }
+}
+
+fn parse_data3(data: &[u8; 0]) -> u8 {
+ match data {
+ b"" => 1,
+ }
+}
+
+fn parse_data4(data: &[u8]) -> u8 {
+ match data { //~ ERROR non-exhaustive patterns
+ b"aaa" => 0,
+ [_, _, _] => 1,
+ }
+}
+
+fn parse_data5(data: &[u8; 3]) -> u8 {
+ match data {
+ b"aaa" => 0,
+ [_, _, _] => 1,
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
+ --> $DIR/type_polymorphic_byte_str_literals.rs:11:11
+ |
+LL | match data {
+ | ^^^^ pattern `&[_, ..]` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `&[u8]`
+
+error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
+ --> $DIR/type_polymorphic_byte_str_literals.rs:23:11
+ |
+LL | match data {
+ | ^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+ = note: the matched value is of type `&[u8]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
+++ /dev/null
-// normalize-stderr-32bit: "-2147483648isize" -> "$$ISIZE_MIN"
-// normalize-stderr-64bit: "-9223372036854775808isize" -> "$$ISIZE_MIN"
-// normalize-stderr-32bit: "2147483647isize" -> "$$ISIZE_MAX"
-// normalize-stderr-64bit: "9223372036854775807isize" -> "$$ISIZE_MAX"
-// normalize-stderr-32bit: "4294967295usize" -> "$$USIZE_MAX"
-// normalize-stderr-64bit: "18446744073709551615usize" -> "$$USIZE_MAX"
-
-#![feature(precise_pointer_size_matching)]
-#![feature(exclusive_range_pattern)]
-
-#![deny(unreachable_patterns, overlapping_patterns)]
-
-use std::{usize, isize};
-
-fn main() {
- match 0isize {
- isize::MIN ..= isize::MAX => {} // ok
- }
-
- match 0usize {
- 0 ..= usize::MAX => {} // ok
- }
-
- match 0isize { //~ ERROR non-exhaustive patterns
- 1 ..= 8 => {}
- -5 ..= 20 => {}
- }
-
- match 0usize { //~ ERROR non-exhaustive patterns
- 1 ..= 8 => {}
- 5 ..= 20 => {}
- }
-}
+++ /dev/null
-error[E0004]: non-exhaustive patterns: `isize::MIN..=-6_isize` and `21_isize..=isize::MAX` not covered
- --> $DIR/precise_pointer_size_matching.rs:24:11
- |
-LL | match 0isize {
- | ^^^^^^ patterns `isize::MIN..=-6_isize` and `21_isize..=isize::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `isize`
-
-error[E0004]: non-exhaustive patterns: `0_usize` and `21_usize..=usize::MAX` not covered
- --> $DIR/precise_pointer_size_matching.rs:29:11
- |
-LL | match 0usize {
- | ^^^^^^ patterns `0_usize` and `21_usize..=usize::MAX` not covered
- |
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
- = note: the matched value is of type `usize`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0004`.