Skip to content

Commit de91872

Browse files
committed
Add a FusedIterator trait.
This trait can be used to avoid the overhead of a fuse wrapper when an iterator is already well-behaved. Conforming to: RFC 1581 Closes: #35602
1 parent 43c090e commit de91872

29 files changed

+437
-24
lines changed

src/liballoc/boxed.rs

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use core::borrow;
6161
use core::cmp::Ordering;
6262
use core::fmt;
6363
use core::hash::{self, Hash};
64+
use core::iter::FusedIterator;
6465
use core::marker::{self, Unsize};
6566
use core::mem;
6667
use core::ops::{CoerceUnsized, Deref, DerefMut};
@@ -529,6 +530,9 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
529530
#[stable(feature = "rust1", since = "1.0.0")]
530531
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
531532

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

533537
/// `FnBox` is a version of the `FnOnce` intended for use with boxed
534538
/// closure objects. The idea is that where one would normally store a

src/liballoc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
#![feature(unsafe_no_drop_flag, filling_drop)]
9292
#![feature(unsize)]
9393

94-
#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
94+
#![cfg_attr(not(test), feature(fused, raw, fn_traits, placement_new_protocol))]
9595
#![cfg_attr(test, feature(test, box_heap))]
9696

9797
// Allow testing this library

src/libcollections/binary_heap.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
#![stable(feature = "rust1", since = "1.0.0")]
153153

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

984+
#[unstable(feature = "fused", issue = "35602")]
985+
impl<'a, T> FusedIterator for Iter<'a, T> {}
986+
984987
/// An iterator that moves out of a `BinaryHeap`.
985988
#[stable(feature = "rust1", since = "1.0.0")]
986989
#[derive(Clone)]
@@ -1014,6 +1017,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
10141017
#[stable(feature = "rust1", since = "1.0.0")]
10151018
impl<T> ExactSizeIterator for IntoIter<T> {}
10161019

1020+
#[unstable(feature = "fused", issue = "35602")]
1021+
impl<T> FusedIterator for IntoIter<T> {}
1022+
10171023
/// An iterator that drains a `BinaryHeap`.
10181024
#[stable(feature = "drain", since = "1.6.0")]
10191025
pub struct Drain<'a, T: 'a> {
@@ -1046,6 +1052,9 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
10461052
#[stable(feature = "rust1", since = "1.0.0")]
10471053
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
10481054

1055+
#[unstable(feature = "fused", issue = "35602")]
1056+
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
1057+
10491058
#[stable(feature = "rust1", since = "1.0.0")]
10501059
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
10511060
fn from(vec: Vec<T>) -> BinaryHeap<T> {

src/libcollections/btree/map.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use core::cmp::Ordering;
1212
use core::fmt::Debug;
1313
use core::hash::{Hash, Hasher};
14-
use core::iter::{FromIterator, Peekable};
14+
use core::iter::{FromIterator, Peekable, FusedIterator};
1515
use core::marker::PhantomData;
1616
use core::ops::Index;
1717
use core::{fmt, intrinsics, mem, ptr};
@@ -1147,6 +1147,9 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
11471147
}
11481148
}
11491149

1150+
#[unstable(feature = "fused", issue = "35602")]
1151+
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1152+
11501153
impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> {
11511154
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
11521155
if self.length == 0 {
@@ -1216,6 +1219,9 @@ impl<'a, K: 'a, V: 'a> ExactSizeIterator for IterMut<'a, K, V> {
12161219
}
12171220
}
12181221

1222+
#[unstable(feature = "fused", issue = "35602")]
1223+
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
1224+
12191225
impl<K, V> IntoIterator for BTreeMap<K, V> {
12201226
type Item = (K, V);
12211227
type IntoIter = IntoIter<K, V>;
@@ -1338,6 +1344,9 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> {
13381344
}
13391345
}
13401346

1347+
#[unstable(feature = "fused", issue = "35602")]
1348+
impl<K, V> FusedIterator for IntoIter<K, V> {}
1349+
13411350
impl<'a, K, V> Iterator for Keys<'a, K, V> {
13421351
type Item = &'a K;
13431352

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

1374+
#[unstable(feature = "fused", issue = "35602")]
1375+
impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
1376+
13651377
impl<'a, K, V> Clone for Keys<'a, K, V> {
13661378
fn clone(&self) -> Keys<'a, K, V> {
13671379
Keys { inner: self.inner.clone() }
@@ -1392,6 +1404,9 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
13921404
}
13931405
}
13941406

1407+
#[unstable(feature = "fused", issue = "35602")]
1408+
impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
1409+
13951410
impl<'a, K, V> Clone for Values<'a, K, V> {
13961411
fn clone(&self) -> Values<'a, K, V> {
13971412
Values { inner: self.inner.clone() }
@@ -1437,6 +1452,10 @@ impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
14371452
}
14381453
}
14391454

1455+
#[unstable(feature = "fused", issue = "35602")]
1456+
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}
1457+
1458+
14401459
impl<'a, K, V> Range<'a, K, V> {
14411460
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
14421461
let handle = self.front;
@@ -1511,6 +1530,9 @@ impl<'a, K, V> Range<'a, K, V> {
15111530
}
15121531
}
15131532

1533+
#[unstable(feature = "fused", issue = "35602")]
1534+
impl<'a, K, V> FusedIterator for Range<'a, K, V> {}
1535+
15141536
impl<'a, K, V> Clone for Range<'a, K, V> {
15151537
fn clone(&self) -> Range<'a, K, V> {
15161538
Range {
@@ -1574,6 +1596,9 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
15741596
}
15751597
}
15761598

1599+
#[unstable(feature = "fused", issue = "35602")]
1600+
impl<'a, K, V> FusedIterator for RangeMut<'a, K, V> {}
1601+
15771602
impl<'a, K, V> RangeMut<'a, K, V> {
15781603
unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
15791604
let handle = ptr::read(&self.back);

src/libcollections/btree/set.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use core::cmp::Ordering::{self, Less, Greater, Equal};
1515
use core::cmp::{min, max};
1616
use core::fmt::Debug;
1717
use core::fmt;
18-
use core::iter::{Peekable, FromIterator};
18+
use core::iter::{Peekable, FromIterator, FusedIterator};
1919
use core::ops::{BitOr, BitAnd, BitXor, Sub};
2020

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

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

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

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

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

854+
#[unstable(feature = "fused", issue = "35602")]
855+
impl<'a, T> FusedIterator for Range<'a, T> {}
856+
850857
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
851858
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
852859
match (x, y) {
@@ -890,6 +897,9 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
890897
}
891898
}
892899

900+
#[unstable(feature = "fused", issue = "35602")]
901+
impl<'a, T: Ord> FusedIterator for Difference<'a, T> {}
902+
893903
impl<'a, T> Clone for SymmetricDifference<'a, T> {
894904
fn clone(&self) -> SymmetricDifference<'a, T> {
895905
SymmetricDifference {
@@ -920,6 +930,9 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
920930
}
921931
}
922932

933+
#[unstable(feature = "fused", issue = "35602")]
934+
impl<'a, T: Ord> FusedIterator for SymmetricDifference<'a, T> {}
935+
923936
impl<'a, T> Clone for Intersection<'a, T> {
924937
fn clone(&self) -> Intersection<'a, T> {
925938
Intersection {
@@ -960,6 +973,9 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
960973
}
961974
}
962975

976+
#[unstable(feature = "fused", issue = "35602")]
977+
impl<'a, T: Ord> FusedIterator for Intersection<'a, T> {}
978+
963979
impl<'a, T> Clone for Union<'a, T> {
964980
fn clone(&self) -> Union<'a, T> {
965981
Union {
@@ -991,3 +1007,6 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
9911007
(max(a_len, b_len), Some(a_len + b_len))
9921008
}
9931009
}
1010+
1011+
#[unstable(feature = "fused", issue = "35602")]
1012+
impl<'a, T: Ord> FusedIterator for Union<'a, T> {}

src/libcollections/enum_set.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
use core::marker;
2222
use core::fmt;
23-
use core::iter::FromIterator;
23+
use core::iter::{FromIterator, FusedIterator};
2424
use core::ops::{Sub, BitOr, BitAnd, BitXor};
2525

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

269+
#[unstable(feature = "fused", issue = "35602")]
270+
impl<E: CLike> FusedIterator for Iter<E> {}
271+
269272
impl<E: CLike> FromIterator<E> for EnumSet<E> {
270273
fn from_iter<I: IntoIterator<Item = E>>(iter: I) -> EnumSet<E> {
271274
let mut ret = EnumSet::new();

src/libcollections/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#![feature(core_intrinsics)]
3838
#![feature(dropck_parametricity)]
3939
#![feature(fmt_internals)]
40+
#![feature(fused)]
4041
#![feature(heap_api)]
4142
#![feature(inclusive_range)]
4243
#![feature(lang_items)]

src/libcollections/linked_list.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use alloc::boxed::{Box, IntermediateBox};
1919
use core::cmp::Ordering;
2020
use core::fmt;
2121
use core::hash::{Hasher, Hash};
22-
use core::iter::FromIterator;
22+
use core::iter::{FromIterator, FusedIterator};
2323
use core::marker::PhantomData;
2424
use core::mem;
2525
use core::ops::{BoxPlace, InPlace, Place, Placer};
@@ -757,6 +757,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
757757
#[stable(feature = "rust1", since = "1.0.0")]
758758
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
759759

760+
#[unstable(feature = "fused", issue = "35602")]
761+
impl<'a, T> FusedIterator for Iter<'a, T> {}
762+
760763
#[stable(feature = "rust1", since = "1.0.0")]
761764
impl<'a, T> Iterator for IterMut<'a, T> {
762765
type Item = &'a mut T;
@@ -801,6 +804,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
801804
#[stable(feature = "rust1", since = "1.0.0")]
802805
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
803806

807+
#[unstable(feature = "fused", issue = "35602")]
808+
impl<'a, T> FusedIterator for IterMut<'a, T> {}
809+
804810
impl<'a, T> IterMut<'a, T> {
805811
/// Inserts the given element just after the element most recently returned by `.next()`.
806812
/// The inserted element does not appear in the iteration.
@@ -908,6 +914,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
908914
#[stable(feature = "rust1", since = "1.0.0")]
909915
impl<T> ExactSizeIterator for IntoIter<T> {}
910916

917+
#[unstable(feature = "fused", issue = "35602")]
918+
impl<T> FusedIterator for IntoIter<T> {}
919+
911920
#[stable(feature = "rust1", since = "1.0.0")]
912921
impl<T> FromIterator<T> for LinkedList<T> {
913922
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {

src/libcollections/str.rs

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use core::str as core_str;
2323
use core::str::pattern::Pattern;
2424
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
2525
use core::mem;
26+
use core::iter::FusedIterator;
2627
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
2728

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

140+
#[unstable(feature = "fused", issue = "35602")]
141+
impl<'a> FusedIterator for EncodeUtf16<'a> {}
142+
139143
// Return the initial codepoint accumulator for the first byte.
140144
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
141145
// for width 3, and 3 bits for width 4

src/libcollections/string.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
use core::fmt;
5959
use core::hash;
60-
use core::iter::FromIterator;
60+
use core::iter::{FromIterator, FusedIterator};
6161
use core::mem;
6262
use core::ops::{self, Add, AddAssign, Index, IndexMut};
6363
use core::ptr;
@@ -1995,3 +1995,6 @@ impl<'a> DoubleEndedIterator for Drain<'a> {
19951995
self.iter.next_back()
19961996
}
19971997
}
1998+
1999+
#[unstable(feature = "fused", issue = "35602")]
2000+
impl<'a> FusedIterator for Drain<'a> {}

src/libcollections/vec.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use core::cmp::Ordering;
6868
use core::fmt;
6969
use core::hash::{self, Hash};
7070
use core::intrinsics::{arith_offset, assume};
71-
use core::iter::FromIterator;
71+
use core::iter::{FromIterator, FusedIterator};
7272
use core::mem;
7373
use core::ops::{Index, IndexMut};
7474
use core::ops;
@@ -1845,6 +1845,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
18451845
#[stable(feature = "rust1", since = "1.0.0")]
18461846
impl<T> ExactSizeIterator for IntoIter<T> {}
18471847

1848+
#[unstable(feature = "fused", issue = "35602")]
1849+
impl<T> FusedIterator for IntoIter<T> {}
1850+
18481851
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
18491852
impl<T: Clone> Clone for IntoIter<T> {
18501853
fn clone(&self) -> IntoIter<T> {
@@ -1932,3 +1935,6 @@ impl<'a, T> Drop for Drain<'a, T> {
19321935

19331936
#[stable(feature = "rust1", since = "1.0.0")]
19341937
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
1938+
1939+
#[unstable(feature = "fused", issue = "35602")]
1940+
impl<'a, T> FusedIterator for Drain<'a, T> {}

0 commit comments

Comments
 (0)