Skip to content

Implement 1581 (FusedIterator) #35656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 23, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
@@ -61,6 +61,7 @@ use core::borrow;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::iter::FusedIterator;
use core::marker::{self, Unsize};
use core::mem;
use core::ops::{CoerceUnsized, Deref, DerefMut};
@@ -529,6 +530,9 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}

#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}


/// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a
2 changes: 1 addition & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(unsize)]

#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
#![cfg_attr(not(test), feature(fused, raw, fn_traits, placement_new_protocol))]
#![cfg_attr(test, feature(test, box_heap))]

// Allow testing this library
11 changes: 10 additions & 1 deletion src/libcollections/binary_heap.rs
Original file line number Diff line number Diff line change
@@ -152,7 +152,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use core::ops::{Drop, Deref, DerefMut};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem::swap;
use core::mem::size_of;
use core::ptr;
@@ -981,6 +981,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}

/// An iterator that moves out of a `BinaryHeap`.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
@@ -1014,6 +1017,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

/// An iterator that drains a `BinaryHeap`.
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
@@ -1046,6 +1052,9 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
fn from(vec: Vec<T>) -> BinaryHeap<T> {
27 changes: 26 additions & 1 deletion src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
use core::cmp::Ordering;
use core::fmt::Debug;
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, Peekable};
use core::iter::{FromIterator, Peekable, FusedIterator};
use core::marker::PhantomData;
use core::ops::Index;
use core::{fmt, intrinsics, mem, ptr};
@@ -1147,6 +1147,9 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}

impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> {
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
if self.length == 0 {
@@ -1216,6 +1219,9 @@ impl<'a, K: 'a, V: 'a> ExactSizeIterator for IterMut<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}

impl<K, V> IntoIterator for BTreeMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
@@ -1338,6 +1344,9 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<K, V> FusedIterator for IntoIter<K, V> {}

impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;

@@ -1362,6 +1371,9 @@ impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}

impl<'a, K, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> {
Keys { inner: self.inner.clone() }
@@ -1392,6 +1404,9 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Values<'a, K, V> {}

impl<'a, K, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> {
Values { inner: self.inner.clone() }
@@ -1437,6 +1452,10 @@ impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}


impl<'a, K, V> Range<'a, K, V> {
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
let handle = self.front;
@@ -1511,6 +1530,9 @@ impl<'a, K, V> Range<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Range<'a, K, V> {}

impl<'a, K, V> Clone for Range<'a, K, V> {
fn clone(&self) -> Range<'a, K, V> {
Range {
@@ -1574,6 +1596,9 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for RangeMut<'a, K, V> {}

impl<'a, K, V> RangeMut<'a, K, V> {
unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
let handle = ptr::read(&self.back);
21 changes: 20 additions & 1 deletion src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use core::cmp::Ordering::{self, Less, Greater, Equal};
use core::cmp::{min, max};
use core::fmt::Debug;
use core::fmt;
use core::iter::{Peekable, FromIterator};
use core::iter::{Peekable, FromIterator, FusedIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub};

use borrow::Borrow;
@@ -805,6 +805,8 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize { self.iter.len() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Iterator for IntoIter<T> {
@@ -828,6 +830,8 @@ impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize { self.iter.len() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

impl<'a, T> Clone for Range<'a, T> {
fn clone(&self) -> Range<'a, T> {
@@ -847,6 +851,9 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Range<'a, T> {}

/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
@@ -890,6 +897,9 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Difference<'a, T> {}

impl<'a, T> Clone for SymmetricDifference<'a, T> {
fn clone(&self) -> SymmetricDifference<'a, T> {
SymmetricDifference {
@@ -920,6 +930,9 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for SymmetricDifference<'a, T> {}

impl<'a, T> Clone for Intersection<'a, T> {
fn clone(&self) -> Intersection<'a, T> {
Intersection {
@@ -960,6 +973,9 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Intersection<'a, T> {}

impl<'a, T> Clone for Union<'a, T> {
fn clone(&self) -> Union<'a, T> {
Union {
@@ -991,3 +1007,6 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
(max(a_len, b_len), Some(a_len + b_len))
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Union<'a, T> {}
5 changes: 4 additions & 1 deletion src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@

use core::marker;
use core::fmt;
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::ops::{Sub, BitOr, BitAnd, BitXor};

// FIXME(contentions): implement union family of methods? (general design may be
@@ -266,6 +266,9 @@ impl<E: CLike> Iterator for Iter<E> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<E: CLike> FusedIterator for Iter<E> {}

impl<E: CLike> FromIterator<E> for EnumSet<E> {
fn from_iter<I: IntoIterator<Item = E>>(iter: I) -> EnumSet<E> {
let mut ret = EnumSet::new();
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
#![feature(core_intrinsics)]
#![feature(dropck_parametricity)]
#![feature(fmt_internals)]
#![feature(fused)]
#![feature(heap_api)]
#![feature(inclusive_range)]
#![feature(lang_items)]
11 changes: 10 additions & 1 deletion src/libcollections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ use alloc::boxed::{Box, IntermediateBox};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hasher, Hash};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem;
use core::ops::{BoxPlace, InPlace, Place, Placer};
@@ -757,6 +757,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
@@ -801,6 +804,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}

impl<'a, T> IterMut<'a, T> {
/// Inserts the given element just after the element most recently returned by `.next()`.
/// The inserted element does not appear in the iteration.
@@ -908,6 +914,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> FromIterator<T> for LinkedList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
4 changes: 4 additions & 0 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ use core::str as core_str;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
use core::iter::FusedIterator;
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};

use vec_deque::VecDeque;
@@ -136,6 +137,9 @@ impl<'a> Iterator for EncodeUtf16<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for EncodeUtf16<'a> {}

// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4
5 changes: 4 additions & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@

use core::fmt;
use core::hash;
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem;
use core::ops::{self, Add, AddAssign, Index, IndexMut};
use core::ptr;
@@ -1995,3 +1995,6 @@ impl<'a> DoubleEndedIterator for Drain<'a> {
self.iter.next_back()
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Drain<'a> {}
8 changes: 7 additions & 1 deletion src/libcollections/vec.rs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::intrinsics::{arith_offset, assume};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut};
use core::ops;
@@ -1845,6 +1845,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
impl<T: Clone> Clone for IntoIter<T> {
fn clone(&self) -> IntoIter<T> {
@@ -1932,3 +1935,6 @@ impl<'a, T> Drop for Drain<'a, T> {

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Drain<'a, T> {}
15 changes: 14 additions & 1 deletion src/libcollections/vec_deque.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@

use core::cmp::Ordering;
use core::fmt;
use core::iter::{repeat, FromIterator};
use core::iter::{repeat, FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut};
use core::ptr;
@@ -1894,6 +1894,10 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}


/// `VecDeque` mutable iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
@@ -1946,6 +1950,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}

/// A by-value VecDeque iterator
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1980,6 +1987,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

/// A draining VecDeque iterator
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
@@ -2069,6 +2079,9 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PartialEq> PartialEq for VecDeque<A> {
fn eq(&self, other: &VecDeque<A>) -> bool {
18 changes: 18 additions & 0 deletions src/libcore/char.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
use prelude::v1::*;

use char_private::is_printable;
use iter::FusedIterator;
use mem::transmute;

// UTF-8 ranges and tags for encoding characters
@@ -516,6 +517,9 @@ impl ExactSizeIterator for EscapeUnicode {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeUnicode {}

/// An iterator that yields the literal escape code of a `char`.
///
/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
@@ -616,6 +620,9 @@ impl ExactSizeIterator for EscapeDefault {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}

/// An iterator that yields the literal escape code of a `char`.
///
/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its
@@ -637,6 +644,9 @@ impl Iterator for EscapeDebug {
#[unstable(feature = "char_escape_debug", issue = "35068")]
impl ExactSizeIterator for EscapeDebug { }

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDebug {}

/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
/// value.
///
@@ -675,6 +685,9 @@ impl Iterator for EncodeUtf8 {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EncodeUtf8 {}

/// An iterator over `u16` entries represending the UTF-16 encoding of a `char`
/// value.
///
@@ -714,6 +727,8 @@ impl Iterator for EncodeUtf16 {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EncodeUtf16 {}

/// An iterator over an iterator of bytes of the characters the bytes represent
/// as UTF-8
@@ -760,3 +775,6 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
})
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator<Item = u8>> FusedIterator for DecodeUtf8<I> {}
130 changes: 124 additions & 6 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
@@ -330,6 +330,8 @@ pub use self::sources::{Once, once};
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{ExactSizeIterator, Sum, Product};
#[unstable(feature = "fused", issue = "35602")]
pub use self::traits::FusedIterator;

mod iterator;
mod range;
@@ -370,6 +372,10 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
impl<I> ExactSizeIterator for Rev<I>
where I: ExactSizeIterator + DoubleEndedIterator {}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Rev<I>
where I: FusedIterator + DoubleEndedIterator {}

/// An iterator that clones the elements of an underlying iterator.
///
/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its
@@ -413,6 +419,11 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
where I: ExactSizeIterator<Item=&'a T>, T: Clone
{}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, I, T: 'a> FusedIterator for Cloned<I>
where I: FusedIterator<Item=&'a T>, T: Clone
{}

/// An iterator that repeats endlessly.
///
/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its
@@ -451,6 +462,9 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}

/// An iterator that strings two iterators together.
///
/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its
@@ -613,6 +627,13 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
}
}

// Note: *both* must be fused to handle double-ended iterators.
#[unstable(feature = "fused", issue = "35602")]
impl<A, B> FusedIterator for Chain<A, B>
where A: FusedIterator,
B: FusedIterator<Item=A::Item>,
{}

/// An iterator that iterates two other iterators simultaneously.
///
/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its
@@ -823,6 +844,10 @@ unsafe impl<A, B> TrustedRandomAccess for Zip<A, B>

}

#[unstable(feature = "fused", issue = "35602")]
impl<A, B> FusedIterator for Zip<A, B>
where A: FusedIterator, B: FusedIterator, {}

/// An iterator that maps the values of `iter` with `f`.
///
/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its
@@ -919,6 +944,10 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
where F: FnMut(I::Item) -> B {}

#[unstable(feature = "fused", issue = "35602")]
impl<B, I: FusedIterator, F> FusedIterator 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
@@ -979,6 +1008,10 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator, P> FusedIterator 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
@@ -1041,6 +1074,10 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<B, I: FusedIterator, F> FusedIterator 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
@@ -1128,6 +1165,9 @@ unsafe impl<I> TrustedRandomAccess for Enumerate<I>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}

/// An iterator with a `peek()` that returns an optional reference to the next
/// element.
///
@@ -1195,6 +1235,9 @@ impl<I: Iterator> Iterator for Peekable<I> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}

#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator> FusedIterator for Peekable<I> {}

impl<I: Iterator> Peekable<I> {
/// Returns a reference to the next() value without advancing the iterator.
///
@@ -1296,6 +1339,10 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I, P> FusedIterator for SkipWhile<I, P>
where I: FusedIterator, P: FnMut(&I::Item) -> bool {}

/// An iterator that only accepts elements while `predicate` is true.
///
/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its
@@ -1351,6 +1398,10 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I, P> FusedIterator for TakeWhile<I, P>
where I: FusedIterator, P: FnMut(&I::Item) -> bool {}

/// An iterator that skips over `n` elements of `iter`.
///
/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its
@@ -1442,6 +1493,9 @@ impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSize
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Skip<I> where I: FusedIterator {}

/// An iterator that only iterates over the first `n` iterations of `iter`.
///
/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its
@@ -1503,6 +1557,8 @@ impl<I> Iterator for Take<I> where I: Iterator{
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}

/// An iterator to maintain state while iterating another iterator.
///
@@ -1549,6 +1605,10 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<B, I, St, F> FusedIterator for Scan<I, St, F>
where I: FusedIterator, F: FnMut(&mut St, I::Item) -> Option<B> {}

/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
@@ -1635,6 +1695,10 @@ impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> wher
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}

/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
@@ -1651,12 +1715,15 @@ pub struct Fuse<I> {
done: bool
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Fuse<I> where I: Iterator {
type Item = <I as Iterator>::Item;

#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
default fn next(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
None
} else {
@@ -1667,7 +1734,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}

#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
default fn nth(&mut self, n: usize) -> Option<I::Item> {
if self.done {
None
} else {
@@ -1678,7 +1745,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}

#[inline]
fn last(self) -> Option<I::Item> {
default fn last(self) -> Option<I::Item> {
if self.done {
None
} else {
@@ -1687,7 +1754,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}

#[inline]
fn count(self) -> usize {
default fn count(self) -> usize {
if self.done {
0
} else {
@@ -1696,7 +1763,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
default fn size_hint(&self) -> (usize, Option<usize>) {
if self.done {
(0, Some(0))
} else {
@@ -1708,7 +1775,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
#[inline]
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
None
} else {
@@ -1719,6 +1786,53 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
}
}

unsafe impl<I> TrustedRandomAccess for Fuse<I>
where I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
self.iter.get_unchecked(i)
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> Iterator for Fuse<I> where I: FusedIterator {
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next()
}

#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
self.iter.nth(n)
}

#[inline]
fn last(self) -> Option<I::Item> {
self.iter.last()
}

#[inline]
fn count(self) -> usize {
self.iter.count()
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

#[unstable(feature = "fused", reason = "recently added", issue = "35602")]
impl<I> DoubleEndedIterator for Fuse<I>
where I: DoubleEndedIterator + FusedIterator
{
#[inline]
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next_back()
}
}


#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {}

@@ -1788,3 +1902,7 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
where F: FnMut(&I::Item) {}

#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F>
where F: FnMut(&I::Item) {}
24 changes: 23 additions & 1 deletion src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use option::Option::{self, Some, None};
use marker::Sized;
use usize;

use super::{DoubleEndedIterator, ExactSizeIterator, Iterator};
use super::{DoubleEndedIterator, ExactSizeIterator, Iterator, FusedIterator};

/// Objects that can be stepped over in both directions.
///
@@ -364,6 +364,10 @@ impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for StepBy<A, ops::RangeFrom<A>>
where A: Clone, for<'a> &'a A: Add<&'a A, Output = A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
type Item = A;
@@ -401,6 +405,9 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::Range<A>> {}

#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
@@ -468,6 +475,9 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::RangeInclusive<A>> {}

macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
@@ -526,6 +536,10 @@ impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::Range<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> where
for<'a> &'a A: Add<&'a A, Output = A>
@@ -540,6 +554,10 @@ impl<A: Step> Iterator for ops::RangeFrom<A> where
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::RangeFrom<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> where
for<'a> &'a A: Add<&'a A, Output = A>
@@ -638,3 +656,7 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
n
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::RangeInclusive<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
11 changes: 10 additions & 1 deletion src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use marker;
use option::Option::{self, Some, None};
use usize;

use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator};
use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator, FusedIterator};

/// An iterator that repeats an element endlessly.
///
@@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
@@ -138,6 +141,9 @@ impl<T> ExactSizeIterator for Empty<T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
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")]
@@ -213,6 +219,9 @@ impl<T> ExactSizeIterator for Once<T> {
}
}

#[unstable(feature = "fused", issue = "35602")]
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
16 changes: 16 additions & 0 deletions src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
@@ -658,3 +658,19 @@ macro_rules! float_sum_product {

integer_sum_product! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
float_sum_product! { f32 f64 }

/// An iterator that always continues to yield `None` when exhausted.
///
/// Calling next on a fused iterator that has returned `None` once is guaranteed
/// to return `None` again. This trait is should be implemented by all iterators
/// that behave this way because it allows for some significant optimizations.
///
/// Note: In general, you should not use `FusedIterator` in generic bounds if
/// you need a fused iterator. Instead, you should just call `Iterator::fused()`
/// on the iterator. If the iterator is already fused, the additional `Fuse`
/// wrapper will be a no-op with no performance penalty.
#[unstable(feature = "fused", issue = "35602")]
pub trait FusedIterator: Iterator {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
14 changes: 12 additions & 2 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
@@ -144,8 +144,8 @@ use self::Option::*;
use clone::Clone;
use convert::From;
use default::Default;
use iter::ExactSizeIterator;
use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
use iter::{Iterator, FromIterator, IntoIterator, ExactSizeIterator, DoubleEndedIterator};
use iter::FusedIterator;
use mem;
use ops::FnOnce;
use result::Result::{Ok, Err};
@@ -796,6 +796,7 @@ impl<A> DoubleEndedIterator for Item<A> {
}

impl<A> ExactSizeIterator for Item<A> {}
impl<A> FusedIterator for Item<A> {}

/// An iterator over a reference of the contained item in an Option.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -821,6 +822,9 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> ExactSizeIterator for Iter<'a, A> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, A> FusedIterator for Iter<'a, A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> Clone for Iter<'a, A> {
fn clone(&self) -> Iter<'a, A> {
@@ -852,6 +856,9 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, A> FusedIterator for IterMut<'a, A> {}

/// An iterator over the item contained inside an Option.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -876,6 +883,9 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> ExactSizeIterator for IntoIter<A> {}

#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for IntoIter<A> {}

/////////////////////////////////////////////////////////////////////////////
// FromIterator
/////////////////////////////////////////////////////////////////////////////
10 changes: 10 additions & 0 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
@@ -241,6 +241,7 @@ use self::Result::{Ok, Err};
use clone::Clone;
use fmt;
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
use iter::FusedIterator;
use ops::FnOnce;
use option::Option::{self, None, Some};

@@ -869,6 +870,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } }
@@ -901,6 +905,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}

/// An iterator over the value in a `Ok` variant of a `Result`.
#[derive(Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -928,6 +935,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}

/////////////////////////////////////////////////////////////////////////////
// FromIterator
/////////////////////////////////////////////////////////////////////////////
25 changes: 25 additions & 0 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
@@ -992,6 +992,9 @@ iterator!{struct Iter -> *const T, &'a T}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
@@ -1110,6 +1113,9 @@ iterator!{struct IterMut -> *mut T, &'a mut T}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}

/// An internal abstraction over the splitting iterators, so that
/// splitn, splitn_mut etc can be implemented once.
#[doc(hidden)]
@@ -1202,6 +1208,9 @@ impl<'a, T, P> SplitIter for Split<'a, T, P> where P: FnMut(&T) -> bool {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, P> FusedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool {}

/// An iterator over the subslices of the vector which are separated
/// by elements that match `pred`.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1292,6 +1301,9 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {}

/// An private iterator over subslices separated by elements that
/// match a predicate function, splitting at most a fixed number of
/// times.
@@ -1408,6 +1420,10 @@ macro_rules! forward_iterator {
self.inner.size_hint()
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P>
where P: FnMut(&T) -> bool {}
}
}

@@ -1506,6 +1522,9 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Windows<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Windows<'a, T> {}

/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a
/// time).
///
@@ -1609,6 +1628,9 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Chunks<'a, T> {}

/// An iterator over a slice in (non-overlapping) mutable chunks (`size`
/// elements at a time). When the slice len is not evenly divided by the chunk
/// size, the last slice of the iteration will be the remainder.
@@ -1704,6 +1726,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for ChunksMut<'a, T> {}

//
// Free functions
//
25 changes: 24 additions & 1 deletion src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ use convert::AsRef;
use default::Default;
use fmt;
use iter::ExactSizeIterator;
use iter::{Map, Cloned, Iterator, DoubleEndedIterator};
use iter::{Map, Cloned, Iterator, DoubleEndedIterator, FusedIterator};
use marker::Sized;
use mem;
use ops::{Fn, FnMut, FnOnce};
@@ -454,6 +454,9 @@ impl<'a> DoubleEndedIterator for Chars<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Chars<'a> {}

impl<'a> Chars<'a> {
/// View the underlying data as a subslice of the original data.
///
@@ -525,6 +528,9 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for CharIndices<'a> {}

impl<'a> CharIndices<'a> {
/// View the underlying data as a subslice of the original data.
///
@@ -593,6 +599,9 @@ impl<'a> ExactSizeIterator for Bytes<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Bytes<'a> {}

/// This macro generates a Clone impl for string pattern API
/// wrapper types of the form X<'a, P>
macro_rules! derive_pattern_clone {
@@ -739,6 +748,13 @@ macro_rules! generate_pattern_iterators {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P>
where P::Searcher: ReverseSearcher<'a> {}

generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
$forward_iterator,
$reverse_iterator, $iterty);
@@ -1088,6 +1104,9 @@ impl<'a> DoubleEndedIterator for Lines<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Lines<'a> {}

/// Created with the method [`lines_any()`].
///
/// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any
@@ -1151,6 +1170,10 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
#[allow(deprecated)]
impl<'a> FusedIterator for LinesAny<'a> {}

/*
Section: Comparing strings
*/
6 changes: 6 additions & 0 deletions src/librustc_unicode/char.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use core::char::CharExt as C;
use core::iter::FusedIterator;
use core::fmt;
use tables::{conversions, derived_property, general_category, property};

@@ -62,6 +63,9 @@ impl Iterator for ToLowercase {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for ToLowercase {}

/// Returns an iterator that yields the uppercase equivalent of a `char`.
///
/// This `struct` is created by the [`to_uppercase()`] method on [`char`]. See
@@ -80,6 +84,8 @@ impl Iterator for ToUppercase {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for ToUppercase {}

enum CaseMappingIter {
Three(char, char, char),
1 change: 1 addition & 0 deletions src/librustc_unicode/lib.rs
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
#![feature(char_escape_debug)]
#![feature(core_char_ext)]
#![feature(decode_utf8)]
#![feature(fused)]
#![feature(lang_items)]
#![feature(staged_api)]
#![feature(unicode)]
9 changes: 8 additions & 1 deletion src/librustc_unicode/u_str.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
//! methods provided by the unicode parts of the CharExt trait.
use core::char;
use core::iter::Filter;
use core::iter::{Filter, FusedIterator};
use core::str::Split;

/// An iterator over the non-whitespace substrings of a string,
@@ -177,6 +177,10 @@ impl<I> Iterator for Utf16Encoder<I>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Utf16Encoder<I>
where I: FusedIterator<Item = char> {}

impl<'a> Iterator for SplitWhitespace<'a> {
type Item = &'a str;

@@ -189,3 +193,6 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
self.inner.next_back()
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for SplitWhitespace<'a> {}
4 changes: 4 additions & 0 deletions src/libstd/ascii.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ use prelude::v1::*;

use mem;
use ops::Range;
use iter::FusedIterator;

/// Extension methods for ASCII-subset only operations on string slices.
///
@@ -368,6 +369,9 @@ impl DoubleEndedIterator for EscapeDefault {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for EscapeDefault {}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}


static ASCII_LOWERCASE_MAP: [u8; 256] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
17 changes: 16 additions & 1 deletion src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use borrow::Borrow;
use cmp::max;
use fmt::{self, Debug};
use hash::{Hash, Hasher, BuildHasher, SipHasher13};
use iter::FromIterator;
use iter::{FromIterator, FusedIterator};
use mem::{self, replace};
use ops::{Deref, Index};
use rand::{self, Rng};
@@ -1484,6 +1484,9 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
@@ -1495,6 +1498,8 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> Iterator for IntoIter<K, V> {
@@ -1507,6 +1512,8 @@ impl<K, V> Iterator for IntoIter<K, V> {
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<K, V> FusedIterator for IntoIter<K, V> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Keys<'a, K, V> {
@@ -1519,6 +1526,8 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Values<'a, K, V> {
@@ -1531,6 +1540,8 @@ impl<'a, K, V> Iterator for Values<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Values<'a, K, V> {}

#[stable(feature = "map_values_mut", since = "1.10.0")]
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
@@ -1543,6 +1554,8 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Drain<'a, K, V> {
@@ -1555,6 +1568,8 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Drain<'a, K, V> {}

impl<'a, K, V> Entry<'a, K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
28 changes: 27 additions & 1 deletion src/libstd/collections/hash/set.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
use borrow::Borrow;
use fmt;
use hash::{Hash, BuildHasher};
use iter::{Chain, FromIterator};
use iter::{Chain, FromIterator, FusedIterator};
use ops::{BitOr, BitAnd, BitXor, Sub};

use super::Recover;
@@ -906,6 +906,8 @@ impl<'a, K> Iterator for Iter<'a, K> {
impl<'a, K> ExactSizeIterator for Iter<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Iter<'a, K> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<K> Iterator for IntoIter<K> {
@@ -918,6 +920,8 @@ impl<K> Iterator for IntoIter<K> {
impl<K> ExactSizeIterator for IntoIter<K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<K> FusedIterator for IntoIter<K> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K> Iterator for Drain<'a, K> {
@@ -930,6 +934,8 @@ impl<'a, K> Iterator for Drain<'a, K> {
impl<'a, K> ExactSizeIterator for Drain<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Drain<'a, K> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Intersection<'a, T, S> {
@@ -961,6 +967,11 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Intersection<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Difference<'a, T, S> {
fn clone(&self) -> Difference<'a, T, S> {
@@ -991,6 +1002,11 @@ impl<'a, T, S> Iterator for Difference<'a, T, S>
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Difference<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> {
fn clone(&self) -> SymmetricDifference<'a, T, S> {
@@ -1008,11 +1024,21 @@ impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Union<'a, T, S> {
fn clone(&self) -> Union<'a, T, S> { Union { iter: self.iter.clone() } }
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Union<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Iterator for Union<'a, T, S>
where T: Eq + Hash, S: BuildHasher
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -232,6 +232,7 @@
#![feature(float_from_str_radix)]
#![feature(fn_traits)]
#![feature(fnbox)]
#![feature(fused)]
#![feature(hashmap_hasher)]
#![feature(heap_api)]
#![feature(inclusive_range)]
8 changes: 7 additions & 1 deletion src/libstd/path.rs
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ use fmt;
use fs;
use hash::{Hash, Hasher};
use io;
use iter;
use iter::{self, FusedIterator};
use mem;
use ops::{self, Deref};
use string::String;
@@ -858,6 +858,9 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Iter<'a> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Components<'a> {
type Item = Component<'a>;
@@ -958,6 +961,9 @@ impl<'a> DoubleEndedIterator for Components<'a> {
}
}

#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Components<'a> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> cmp::PartialEq for Components<'a> {
fn eq(&self, other: &Components<'a>) -> bool {