Skip to content

Commit 0bd99f9

Browse files
authored
Auto merge of #35656 - Stebalien:fused, r=alexcrichton
Implement 1581 (FusedIterator) * [ ] Implement on patterns. See #27721 (comment). * [ ] Handle OS Iterators. A bunch of iterators (`Args`, `Env`, etc.) in libstd wrap platform specific iterators. The current ones all appear to be well-behaved but can we assume that future ones will be? * [ ] Does someone want to audit this? On first glance, all of the iterators on which I implemented `FusedIterator` appear to be well-behaved but there are a *lot* of them so a second pair of eyes would be nice. * I haven't touched rustc internal iterators (or the internal rand) because rustc doesn't actually call `fuse()`. * `FusedIterator` can't be implemented on `std::io::{Bytes, Chars}`. Closes: #35602 (Tracking Issue) Implements: rust-lang/rfcs#1581
2 parents 43204ff + de91872 commit 0bd99f9

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;
@@ -980,6 +980,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
980980
#[stable(feature = "rust1", since = "1.0.0")]
981981
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
982982

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

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

1054+
#[unstable(feature = "fused", issue = "35602")]
1055+
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
1056+
10481057
#[stable(feature = "rust1", since = "1.0.0")]
10491058
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
10501059
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};
@@ -754,6 +754,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
754754
#[stable(feature = "rust1", since = "1.0.0")]
755755
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
756756

757+
#[unstable(feature = "fused", issue = "35602")]
758+
impl<'a, T> FusedIterator for Iter<'a, T> {}
759+
757760
#[stable(feature = "rust1", since = "1.0.0")]
758761
impl<'a, T> Iterator for IterMut<'a, T> {
759762
type Item = &'a mut T;
@@ -798,6 +801,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
798801
#[stable(feature = "rust1", since = "1.0.0")]
799802
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
800803

804+
#[unstable(feature = "fused", issue = "35602")]
805+
impl<'a, T> FusedIterator for IterMut<'a, T> {}
806+
801807
impl<'a, T> IterMut<'a, T> {
802808
/// Inserts the given element just after the element most recently returned by `.next()`.
803809
/// The inserted element does not appear in the iteration.
@@ -905,6 +911,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
905911
#[stable(feature = "rust1", since = "1.0.0")]
906912
impl<T> ExactSizeIterator for IntoIter<T> {}
907913

914+
#[unstable(feature = "fused", issue = "35602")]
915+
impl<T> FusedIterator for IntoIter<T> {}
916+
908917
#[stable(feature = "rust1", since = "1.0.0")]
909918
impl<T> FromIterator<T> for LinkedList<T> {
910919
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)