From fd6505063b1610b45f351dcd5dce1fadb97d8d28 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 18 Jun 2016 15:58:07 +0200 Subject: [PATCH] Annotate all core iterators with their fusedness For almost all of these iterators the fusedness is straightforward and unlikely to change (e.g. making a memory-safe slice iterator that is not fused is actually a hard thing), but there is exactly one exception: `Chain`. The extension to make it fused is trivial and shouldn't have any performance implications. --- src/libcore/char.rs | 8 ++++++ src/libcore/iter/iterator.rs | 3 ++ src/libcore/iter/mod.rs | 53 ++++++++++++++++++++++++++++++++---- src/libcore/iter/range.rs | 2 ++ src/libcore/iter/sources.rs | 6 ++++ src/libcore/ops.rs | 6 ++++ src/libcore/option.rs | 6 ++++ src/libcore/result.rs | 6 ++++ src/libcore/slice.rs | 22 +++++++++++++++ src/libcore/str/mod.rs | 30 ++++++++++++++++++++ 10 files changed, 136 insertions(+), 6 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index d80b456181ae4..56ef2eaceb1a1 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -397,6 +397,8 @@ impl CharExt for char { /// This `struct` is created by the [`escape_unicode()`] method on [`char`]. See /// its documentation for more. /// +/// This iterator is fused. +/// /// [`escape_unicode()`]: ../../std/primitive.char.html#method.escape_unicode /// [`char`]: ../../std/primitive.char.html #[derive(Clone, Debug)] @@ -505,6 +507,8 @@ impl ExactSizeIterator for EscapeUnicode { /// This `struct` is created by the [`escape_default()`] method on [`char`]. See /// its documentation for more. /// +/// This iterator is fused. +/// /// [`escape_default()`]: ../../std/primitive.char.html#method.escape_default /// [`char`]: ../../std/primitive.char.html #[derive(Clone, Debug)] @@ -604,6 +608,8 @@ impl ExactSizeIterator for EscapeDefault { /// value. /// /// Constructed via the `.encode_utf8()` method on `char`. +/// +/// This iterator is fused. #[unstable(feature = "unicode", issue = "27784")] #[derive(Debug)] pub struct EncodeUtf8 { @@ -642,6 +648,8 @@ impl Iterator for EncodeUtf8 { /// value. /// /// Constructed via the `.encode_utf16()` method on `char`. +/// +/// This iterator is fused. #[unstable(feature = "unicode", issue = "27784")] #[derive(Debug)] pub struct EncodeUtf16 { diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 8fb71295a88a6..ab8c8ee7e1a8d 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -626,6 +626,9 @@ pub trait Iterator { /// `next` is called on the underlying iterator, hence any side effects of /// the `next` method will occur. /// + /// If the iterator is exhausted by peeking, calling `next` or `peek` again + /// has unspecified results if the iterator isn't fused. + /// /// [`peek()`]: struct.Peekable.html#method.peek /// /// # Examples diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index b866655bbd53d..adfaa17e8b415 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -374,6 +374,8 @@ impl ExactSizeIterator for Rev /// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`cloned()`]: trait.Iterator.html#method.cloned /// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_cloned", since = "1.1.0")] @@ -417,6 +419,8 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned /// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused because it never returns `None`. +/// /// [`cycle()`]: trait.Iterator.html#method.cycle /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -455,6 +459,8 @@ impl Iterator for Cycle where I: Clone + Iterator { /// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused. +/// /// [`chain()`]: trait.Iterator.html#method.chain /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -476,9 +482,7 @@ pub struct Chain { // - Both: `a` and `b` are remaining // - Front: `a` remaining // - Back: `b` remaining -// -// The fourth state (neither iterator is remaining) only occurs after Chain has -// returned None once, so we don't need to store this state. +// - Neither: Neither iterator is remaining. #[derive(Clone, Debug)] enum ChainState { // both front and back iterator are remaining @@ -487,6 +491,8 @@ enum ChainState { Front, // only back is remaining Back, + // neither + Neither, } #[stable(feature = "rust1", since = "1.0.0")] @@ -508,6 +514,7 @@ impl Iterator for Chain where }, ChainState::Front => self.a.next(), ChainState::Back => self.b.next(), + ChainState::Neither => None, } } @@ -518,6 +525,7 @@ impl Iterator for Chain where ChainState::Both => self.a.count() + self.b.count(), ChainState::Front => self.a.count(), ChainState::Back => self.b.count(), + ChainState::Neither => 0, } } @@ -536,6 +544,7 @@ impl Iterator for Chain where } } ChainState::Back => {} + ChainState::Neither => return None, } if let ChainState::Back = self.state { self.b.nth(n) @@ -558,6 +567,7 @@ impl Iterator for Chain where }, ChainState::Front => self.a.find(predicate), ChainState::Back => self.b.find(predicate), + ChainState::Neither => None, } } @@ -571,12 +581,19 @@ impl Iterator for Chain where b_last.or(a_last) }, ChainState::Front => self.a.last(), - ChainState::Back => self.b.last() + ChainState::Back => self.b.last(), + ChainState::Neither => None, } } #[inline] fn size_hint(&self) -> (usize, Option) { + match self.state { + ChainState::Both => {}, + ChainState::Front => return self.a.size_hint(), + ChainState::Back => return self.b.size_hint(), + ChainState::Neither => return (0, Some(0)), + } let (a_lower, a_upper) = self.a.size_hint(); let (b_lower, b_upper) = self.b.size_hint(); @@ -608,6 +625,7 @@ impl DoubleEndedIterator for Chain where }, ChainState::Front => self.a.next_back(), ChainState::Back => self.b.next_back(), + ChainState::Neither => None, } } } @@ -617,6 +635,8 @@ impl DoubleEndedIterator for Chain where /// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if both interior iterators are fused. +/// /// [`zip()`]: trait.Iterator.html#method.zip /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -629,8 +649,7 @@ pub struct Zip { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where A: Iterator, B: Iterator -{ +impl Iterator for Zip where A: Iterator, B: Iterator { type Item = (A::Item, B::Item); #[inline] @@ -872,6 +891,8 @@ unsafe impl TrustedRandomAccess for Zip /// println!("{:?}", pair); /// } /// ``` +/// +/// This iterator is fused if its interior iterator is fused. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -923,6 +944,8 @@ impl ExactSizeIterator for Map /// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`filter()`]: trait.Iterator.html#method.filter /// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -983,6 +1006,8 @@ impl DoubleEndedIterator for Filter /// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`filter_map()`]: trait.Iterator.html#method.filter_map /// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -1045,6 +1070,8 @@ impl DoubleEndedIterator for FilterMap /// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`enumerate()`]: trait.Iterator.html#method.enumerate /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -1133,6 +1160,8 @@ unsafe impl TrustedRandomAccess for Enumerate /// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`peekable()`]: trait.Iterator.html#method.peekable /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -1335,6 +1364,8 @@ impl Iterator for SkipWhile /// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`take_while()`]: trait.Iterator.html#method.take_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -1390,6 +1421,8 @@ impl Iterator for TakeWhile /// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`skip()`]: trait.Iterator.html#method.skip /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -1481,6 +1514,8 @@ impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSize /// This `struct` is created by the [`take()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused. +/// /// [`take()`]: trait.Iterator.html#method.take /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] @@ -1543,6 +1578,8 @@ impl ExactSizeIterator for Take where I: ExactSizeIterator {} /// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if its interior iterator is fused. +/// /// [`scan()`]: trait.Iterator.html#method.scan /// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -1589,6 +1626,8 @@ impl Iterator for Scan where /// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused if the iterator yielding the iterators is fused. +/// /// [`flat_map()`]: trait.Iterator.html#method.flat_map /// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -1675,6 +1714,8 @@ impl DoubleEndedIterator for FlatMap wher /// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its /// documentation for more. /// +/// This iterator is fused. +/// /// [`fuse()`]: trait.Iterator.html#method.fuse /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 08143567beaf3..5d2bab90049a0 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -144,6 +144,8 @@ step_impl_no_between!(u64 i64); /// The resulting iterator handles overflow by stopping. The `A` /// parameter is the type being iterated over, while `R` is the range /// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`. +/// +/// This iterator is fused if the underlying range iterator is fused. #[derive(Clone, Debug)] #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index ecd4a78b9e760..087db2c8b322e 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -21,6 +21,8 @@ use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator}; /// /// This `struct` is created by the [`repeat()`] function. See its documentation for more. /// +/// This iterator is fused because it never returns `None`. +/// /// [`repeat()`]: fn.repeat.html #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] @@ -100,6 +102,8 @@ pub fn repeat(elt: T) -> Repeat { /// /// This `struct` is created by the [`empty()`] function. See its documentation for more. /// +/// This iterator is fused. +/// /// [`empty()`]: fn.empty.html #[stable(feature = "iter_empty", since = "1.2.0")] pub struct Empty(marker::PhantomData); @@ -179,6 +183,8 @@ pub fn empty() -> Empty { /// /// This `struct` is created by the [`once()`] function. See its documentation for more. /// +/// This iterator is fused. +/// /// [`once()`]: fn.once.html #[derive(Clone, Debug)] #[stable(feature = "iter_once", since = "1.2.0")] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 5e1210b2ff9bd..5007d890e4493 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1489,6 +1489,8 @@ impl fmt::Debug for RangeFull { /// A (half-open) range which is bounded at both ends: { x | start <= x < end }. /// Use `start..end` (two dots) for its shorthand. /// +/// This iterator is fused. +/// /// See the [`contains()`](#method.contains) method for its characterization. /// /// # Examples @@ -1555,6 +1557,8 @@ impl> Range { /// might panic in debug mode or create an endless loop in release mode. This /// overflow behavior might change in the future. /// +/// This iterator is fused because it never returns `None`. +/// /// # Examples /// /// ``` @@ -1654,6 +1658,8 @@ impl> RangeTo { /// An inclusive range which is bounded at both ends: { x | start <= x <= end }. /// Use `start...end` (three dots) for its shorthand. /// +/// This iterator is fused. +/// /// See the [`contains()`](#method.contains) method for its characterization. /// /// # Examples diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 045c1f9feafc6..7e55c6fe6b6c0 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -790,6 +790,8 @@ impl DoubleEndedIterator for Item { impl ExactSizeIterator for Item {} /// An iterator over a reference of the contained item in an Option. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct Iter<'a, A: 'a> { inner: Item<&'a A> } @@ -821,6 +823,8 @@ impl<'a, A> Clone for Iter<'a, A> { } /// An iterator over a mutable reference of the contained item in an Option. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> } @@ -845,6 +849,8 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> { impl<'a, A> ExactSizeIterator for IterMut<'a, A> {} /// An iterator over the item contained inside an Option. +/// +/// This iterator is fused. #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { inner: Item } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 4d9f042fddedc..8c06b535f3929 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -840,6 +840,8 @@ impl<'a, T, E> IntoIterator for &'a mut Result { ///////////////////////////////////////////////////////////////////////////// /// An iterator over a reference to the `Ok` variant of a `Result`. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { inner: Option<&'a T> } @@ -872,6 +874,8 @@ impl<'a, T> Clone for Iter<'a, T> { } /// An iterator over a mutable reference to the `Ok` variant of a `Result`. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> } @@ -899,6 +903,8 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} /// An iterator over the value in a `Ok` variant of a `Result`. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { inner: Option } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 727c26ba9abd1..d030639c252ef 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -902,6 +902,8 @@ macro_rules! make_mut_slice { /// Immutable slice iterator /// +/// This iterator is fused. +/// /// # Examples /// /// Basic usage: @@ -993,6 +995,8 @@ impl<'a, T> Clone for Iter<'a, T> { /// Mutable slice iterator. /// +/// This iterator is fused. +/// /// # Examples /// /// Basic usage: @@ -1103,6 +1107,8 @@ trait SplitIter: DoubleEndedIterator { /// An iterator over subslices separated by elements that match a predicate /// function. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a [T], @@ -1186,6 +1192,8 @@ impl<'a, T, P> SplitIter 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`. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a mut [T], @@ -1308,6 +1316,8 @@ impl> Iterator for GenericSplitN { /// An iterator over subslices separated by elements that match a predicate /// function, limited to a given number of splits. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> @@ -1325,6 +1335,8 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(& /// An iterator over subslices separated by elements that match a /// predicate function, limited to a given number of splits, starting /// from the end of the slice. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> @@ -1341,6 +1353,8 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitN<'a, T, P> where P: FnMut( /// An iterator over subslices separated by elements that match a predicate /// function, limited to a given number of splits. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> @@ -1358,6 +1372,8 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMu /// An iterator over subslices separated by elements that match a /// predicate function, limited to a given number of splits, starting /// from the end of the slice. +/// +/// This iterator is fused. #[stable(feature = "rust1", since = "1.0.0")] pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> @@ -1399,6 +1415,8 @@ forward_iterator! { SplitNMut: T, &'a mut [T] } forward_iterator! { RSplitNMut: T, &'a mut [T] } /// An iterator over overlapping subslices of length `size`. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Windows<'a, T:'a> { @@ -1493,6 +1511,8 @@ impl<'a, T> ExactSizeIterator for Windows<'a, T> {} /// /// When the slice len is not evenly divided by the chunk size, the last slice /// of the iteration will be the remainder. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chunks<'a, T:'a> { @@ -1594,6 +1614,8 @@ impl<'a, T> ExactSizeIterator 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. +/// +/// This iterator is fused. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ChunksMut<'a, T:'a> { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 5fc15fae5199b..92234f50d84fd 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -320,6 +320,8 @@ Section: Iterators /// /// Created with the method [`chars()`]. /// +/// This iterator is fused. +/// /// [`chars()`]: ../../std/primitive.str.html#method.chars #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] @@ -467,6 +469,8 @@ impl<'a> Chars<'a> { } /// Iterator for a string's characters and their byte offsets. +/// +/// This iterator is fused. #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct CharIndices<'a> { @@ -530,6 +534,8 @@ impl<'a> CharIndices<'a> { /// /// Created with the method [`bytes()`]. /// +/// This iterator is fused. +/// /// [`bytes()`]: ../../std/primitive.str.html#method.bytes #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] @@ -850,11 +856,15 @@ generate_pattern_iterators! { forward: /// Created with the method [`split()`]. /// + /// This iterator is fused. + /// /// [`split()`]: ../../std/primitive.str.html#method.split struct Split; reverse: /// Created with the method [`rsplit()`]. /// + /// This iterator is fused. + /// /// [`rsplit()`]: ../../std/primitive.str.html#method.rsplit struct RSplit; stability: @@ -868,11 +878,15 @@ generate_pattern_iterators! { forward: /// Created with the method [`split_terminator()`]. /// + /// This iterator is fused. + /// /// [`split_terminator()`]: ../../std/primitive.str.html#method.split_terminator struct SplitTerminator; reverse: /// Created with the method [`rsplit_terminator()`]. /// + /// This iterator is fused. + /// /// [`rsplit_terminator()`]: ../../std/primitive.str.html#method.rsplit_terminator struct RSplitTerminator; stability: @@ -928,11 +942,15 @@ generate_pattern_iterators! { forward: /// Created with the method [`splitn()`]. /// + /// This iterator is fused. + /// /// [`splitn()`]: ../../std/primitive.str.html#method.splitn struct SplitN; reverse: /// Created with the method [`rsplitn()`]. /// + /// This iterator is fused. + /// /// [`rsplitn()`]: ../../std/primitive.str.html#method.rsplitn struct RSplitN; stability: @@ -979,11 +997,15 @@ generate_pattern_iterators! { forward: /// Created with the method [`match_indices()`]. /// + /// This iterator is fused. + /// /// [`match_indices()`]: ../../std/primitive.str.html#method.match_indices struct MatchIndices; reverse: /// Created with the method [`rmatch_indices()`]. /// + /// This iterator is fused. + /// /// [`rmatch_indices()`]: ../../std/primitive.str.html#method.rmatch_indices struct RMatchIndices; stability: @@ -1032,11 +1054,15 @@ generate_pattern_iterators! { forward: /// Created with the method [`matches()`]. /// + /// This iterator is fused. + /// /// [`matches()`]: ../../std/primitive.str.html#method.matches struct Matches; reverse: /// Created with the method [`rmatches()`]. /// + /// This iterator is fused. + /// /// [`rmatches()`]: ../../std/primitive.str.html#method.rmatches struct RMatches; stability: @@ -1048,6 +1074,8 @@ generate_pattern_iterators! { /// Created with the method [`lines()`]. /// +/// This iterator is fused. +/// /// [`lines()`]: ../../std/primitive.str.html#method.lines #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] @@ -1078,6 +1106,8 @@ impl<'a> DoubleEndedIterator for Lines<'a> { /// Created with the method [`lines_any()`]. /// +/// This iterator is fused. +/// /// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]