]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #42169 - scottmcm:new-step-trait-issue, r=alexcrichton
authorCorey Farwell <coreyf@rwell.org>
Fri, 26 May 2017 14:20:25 +0000 (10:20 -0400)
committerGitHub <noreply@github.com>
Fri, 26 May 2017 14:20:25 +0000 (10:20 -0400)
Give step_trait a distinct tracking issue from step_by

iterator_step_by has decoupled their futures, so the tracking issue should split.

Old issue: https://github.com/rust-lang/rust/issues/27741
New issue: https://github.com/rust-lang/rust/issues/42168

r? @alexcrichton (another follow-up to closed PR https://github.com/rust-lang/rust/pull/42110#issuecomment-303176049)

1  2 
src/libcore/iter/mod.rs
src/libcore/iter/range.rs

diff --combined src/libcore/iter/mod.rs
index f9b818f5bff357dbac3615b396eb48e1a43305cf,785c26efdc804e4a922b3a3b286a2a4077e3c653..54919a414786d7074a71fd3964ec8c6145473481
@@@ -309,7 -309,7 +309,7 @@@ pub use self::iterator::Iterator
  
  #[unstable(feature = "step_trait",
             reason = "likely to be replaced by finer-grained traits",
-            issue = "27741")]
+            issue = "42168")]
  pub use self::range::Step;
  #[unstable(feature = "step_by", reason = "recent addition",
             issue = "27741")]
@@@ -1690,7 -1690,7 +1690,7 @@@ impl<I> Iterator for Skip<I> where I: I
  #[stable(feature = "rust1", since = "1.0.0")]
  impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
  
 -#[stable(feature = "double_ended_skip_iterator", since = "1.8.0")]
 +#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")]
  impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSizeIterator {
      fn next_back(&mut self) -> Option<Self::Item> {
          if self.len() > 0 {
index 02d38ccea44eadcb2b95caee0450fbecd7d8d279,8d370f9675f3ea81081a484ee485bff0e199def9..e02823fd81280f7d44011fa9f277f83d0c2a9608
@@@ -20,7 -20,7 +20,7 @@@ use super::{FusedIterator, TrustedLen}
  /// two `Step` objects.
  #[unstable(feature = "step_trait",
             reason = "likely to be replaced by finer-grained traits",
-            issue = "27741")]
+            issue = "42168")]
  pub trait Step: PartialOrd + Sized {
      /// Steps `self` if possible.
      fn step(&self, by: &Self) -> Option<Self>;
@@@ -55,7 -55,7 +55,7 @@@ macro_rules! step_impl_unsigned 
      ($($t:ty)*) => ($(
          #[unstable(feature = "step_trait",
                     reason = "likely to be replaced by finer-grained traits",
-                    issue = "27741")]
+                    issue = "42168")]
          impl Step for $t {
              #[inline]
              fn step(&self, by: &$t) -> Option<$t> {
@@@ -115,7 -115,7 +115,7 @@@ macro_rules! step_impl_signed 
      ($($t:ty)*) => ($(
          #[unstable(feature = "step_trait",
                     reason = "likely to be replaced by finer-grained traits",
-                    issue = "27741")]
+                    issue = "42168")]
          impl Step for $t {
              #[inline]
              fn step(&self, by: &$t) -> Option<$t> {
@@@ -187,7 -187,7 +187,7 @@@ macro_rules! step_impl_no_between 
      ($($t:ty)*) => ($(
          #[unstable(feature = "step_trait",
                     reason = "likely to be replaced by finer-grained traits",
-                    issue = "27741")]
+                    issue = "42168")]
          impl Step for $t {
              #[inline]
              fn step(&self, by: &$t) -> Option<$t> {
@@@ -403,35 -403,61 +403,35 @@@ impl<A: Step + Clone> Iterator for Step
  
      #[inline]
      fn next(&mut self) -> Option<A> {
 -        use ops::RangeInclusive::*;
 -
 -        // this function has a sort of odd structure due to borrowck issues
 -        // we may need to replace self.range, so borrows of start and end need to end early
 -
 -        let (finishing, n) = match self.range {
 -            Empty { .. } => return None, // empty iterators yield no values
 -
 -            NonEmpty { ref mut start, ref mut end } => {
 -                let rev = self.step_by.is_negative();
 -
 -                // march start towards (maybe past!) end and yield the old value
 -                if (rev && start >= end) ||
 -                   (!rev && start <= end)
 -                {
 -                    match start.step(&self.step_by) {
 -                        Some(mut n) => {
 -                            mem::swap(start, &mut n);
 -                            (None, Some(n)) // yield old value, remain non-empty
 -                        },
 -                        None => {
 -                            let mut n = end.clone();
 -                            mem::swap(start, &mut n);
 -                            (None, Some(n)) // yield old value, remain non-empty
 -                        }
 -                    }
 -                } else {
 -                    // found range in inconsistent state (start at or past end), so become empty
 -                    (Some(end.replace_zero()), None)
 -                }
 -            }
 -        };
 +        let rev = self.step_by.is_negative();
  
 -        // turn into an empty iterator if we've reached the end
 -        if let Some(end) = finishing {
 -            self.range = Empty { at: end };
 +        if (rev && self.range.start >= self.range.end) ||
 +           (!rev && self.range.start <= self.range.end)
 +        {
 +            match self.range.start.step(&self.step_by) {
 +                Some(n) => {
 +                    Some(mem::replace(&mut self.range.start, n))
 +                },
 +                None => {
 +                    let last = self.range.start.replace_one();
 +                    self.range.end.replace_zero();
 +                    self.step_by.replace_one();
 +                    Some(last)
 +                },
 +            }
 +        }
 +        else {
 +            None
          }
 -
 -        n
      }
  
      #[inline]
      fn size_hint(&self) -> (usize, Option<usize>) {
 -        use ops::RangeInclusive::*;
 -
 -        match self.range {
 -            Empty { .. } => (0, Some(0)),
 -
 -            NonEmpty { ref start, ref end } =>
 -                match Step::steps_between(start,
 -                                          end,
 -                                          &self.step_by) {
 -                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
 -                    None       => (0, None)
 -                }
 +        match Step::steps_between(&self.range.start,
 +                                  &self.range.end,
 +                                  &self.step_by) {
 +            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
 +            None       => (0, None)
          }
      }
  }
@@@ -557,31 -583,56 +557,31 @@@ impl<A: Step> Iterator for ops::RangeIn
  
      #[inline]
      fn next(&mut self) -> Option<A> {
 -        use ops::RangeInclusive::*;
 -
 -        // this function has a sort of odd structure due to borrowck issues
 -        // we may need to replace self, so borrows of self.start and self.end need to end early
 -
 -        let (finishing, n) = match *self {
 -            Empty { .. } => (None, None), // empty iterators yield no values
 -
 -            NonEmpty { ref mut start, ref mut end } => {
 -                if start == end {
 -                    (Some(end.replace_one()), Some(start.replace_one()))
 -                } else if start < end {
 -                    let mut n = start.add_one();
 -                    mem::swap(&mut n, start);
 -
 -                    // if the iterator is done iterating, it will change from
 -                    // NonEmpty to Empty to avoid unnecessary drops or clones,
 -                    // we'll reuse either start or end (they are equal now, so
 -                    // it doesn't matter which) to pull out end, we need to swap
 -                    // something back in
 -
 -                    (if n == *end { Some(end.replace_one()) } else { None },
 -                    // ^ are we done yet?
 -                    Some(n)) // < the value to output
 -                } else {
 -                    (Some(start.replace_one()), None)
 -                }
 -            }
 -        };
 -
 -        // turn into an empty iterator if this is the last value
 -        if let Some(end) = finishing {
 -            *self = Empty { at: end };
 +        use cmp::Ordering::*;
 +
 +        match self.start.partial_cmp(&self.end) {
 +            Some(Less) => {
 +                let n = self.start.add_one();
 +                Some(mem::replace(&mut self.start, n))
 +            },
 +            Some(Equal) => {
 +                let last = self.start.replace_one();
 +                self.end.replace_zero();
 +                Some(last)
 +            },
 +            _ => None,
          }
 -
 -        n
      }
  
      #[inline]
      fn size_hint(&self) -> (usize, Option<usize>) {
 -        use ops::RangeInclusive::*;
 -
 -        match *self {
 -            Empty { .. } => (0, Some(0)),
 +        if !(self.start <= self.end) {
 +            return (0, Some(0));
 +        }
  
 -            NonEmpty { ref start, ref end } =>
 -                match Step::steps_between_by_one(start, end) {
 -                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
 -                    None => (0, None),
 -                }
 +        match Step::steps_between_by_one(&self.start, &self.end) {
 +            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
 +            None => (0, None),
          }
      }
  }
@@@ -593,20 -644,33 +593,20 @@@ impl<A: Step> DoubleEndedIterator for o
  {
      #[inline]
      fn next_back(&mut self) -> Option<A> {
 -        use ops::RangeInclusive::*;
 -
 -        // see Iterator::next for comments
 -
 -        let (finishing, n) = match *self {
 -            Empty { .. } => return None,
 -
 -            NonEmpty { ref mut start, ref mut end } => {
 -                if start == end {
 -                    (Some(start.replace_one()), Some(end.replace_one()))
 -                } else if start < end {
 -                    let mut n = end.sub_one();
 -                    mem::swap(&mut n, end);
 -
 -                    (if n == *start { Some(start.replace_one()) } else { None },
 -                     Some(n))
 -                } else {
 -                    (Some(end.replace_one()), None)
 -                }
 -            }
 -        };
 -
 -        if let Some(start) = finishing {
 -            *self = Empty { at: start };
 +        use cmp::Ordering::*;
 +
 +        match self.start.partial_cmp(&self.end) {
 +            Some(Less) => {
 +                let n = self.end.sub_one();
 +                Some(mem::replace(&mut self.end, n))
 +            },
 +            Some(Equal) => {
 +                let last = self.end.replace_zero();
 +                self.start.replace_one();
 +                Some(last)
 +            },
 +            _ => None,
          }
 -
 -        n
      }
  }