From 1d5983aded687149239e8943debd51abdce5d27b Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Fri, 13 Mar 2015 11:35:53 -0700 Subject: [PATCH] Deprecate range, range_step, count, distributions This commit deprecates the `count`, `range` and `range_step` functions in `iter`, in favor of range notation. To recover all existing functionality, a new `step_by` adapter is provided directly on `ops::Range` and `ops::RangeFrom`. [breaking-change] --- src/libcollections/lib.rs | 1 + src/libcollections/slice.rs | 6 +- src/libcore/iter.rs | 182 +++++++++++++++++---------- src/libcore/prelude.rs | 1 + src/libcoretest/iter.rs | 12 +- src/librand/distributions/mod.rs | 2 - src/librustc/middle/infer/combine.rs | 2 +- src/librustc_back/lib.rs | 1 + src/librustc_back/svh.rs | 3 +- src/librustc_trans/back/lto.rs | 4 +- src/libstd/ascii.rs | 4 +- src/libstd/net/ip.rs | 2 +- src/libstd/os.rs | 1 - src/libstd/prelude/v1.rs | 1 + src/libstd/sys/unix/os.rs | 2 +- src/libsyntax/parse/parser.rs | 3 +- 16 files changed, 134 insertions(+), 93 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index f7943c0bb9140..e90186d63b4dc 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -33,6 +33,7 @@ #![feature(unsafe_destructor)] #![feature(unique)] #![feature(unsafe_no_drop_flag)] +#![feature(step_by)] #![cfg_attr(test, feature(rand, rustc_private, test))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 2503001b44dad..e1c27095b2f43 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -92,7 +92,7 @@ use core::clone::Clone; use core::cmp::Ordering::{self, Greater, Less}; use core::cmp::{self, Ord, PartialEq}; use core::iter::{Iterator, IteratorExt}; -use core::iter::{range_step, MultiplicativeIterator}; +use core::iter::MultiplicativeIterator; use core::marker::Sized; use core::mem::size_of; use core::mem; @@ -1387,7 +1387,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // We could hardcode the sorting comparisons here, and we could // manipulate/step the pointers themselves, rather than repeatedly // .offset-ing. - for start in range_step(0, len, insertion) { + for start in (0.. len).step_by(insertion) { // start <= i < len; for i in start..cmp::min(start + insertion, len) { // j satisfies: start <= j <= i; @@ -1427,7 +1427,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // a time, placing the result in `buf_tmp`. // 0 <= start <= len. - for start in range_step(0, len, 2 * width) { + for start in (0..len).step_by(2 * width) { // manipulate pointers directly for speed (rather than // using a `for` loop with `range` and `.offset` inside // that loop). diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 237dbe492baec..8ebedb66851d5 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -65,7 +65,7 @@ use default::Default; use marker; use mem; use num::{ToPrimitive, Int}; -use ops::{Add, Deref, FnMut}; +use ops::{Add, Deref, FnMut, RangeFrom}; use option::Option; use option::Option::{Some, None}; use marker::Sized; @@ -2366,34 +2366,101 @@ impl Iterator for Unfold where F: FnMut(&mut St) -> Option { } } +/// An adapter for stepping range iterators by a custom amount. +/// +/// 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}`. +#[derive(Clone)] +#[unstable(feature = "step_by", reason = "recent addition")] +pub struct StepBy { + step_by: A, + range: R, +} + +impl RangeFrom { + /// Creates an iterator starting at the same point, but stepping by + /// the given amount at each iteration. + /// + /// # Examples + /// + /// ```ignore + /// for i in (0u8..).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints all even `u8` values. + #[unstable(feature = "step_by", reason = "recent addition")] + pub fn step_by(self, by: A) -> StepBy { + StepBy { + step_by: by, + range: self + } + } +} + +impl ::ops::Range { + /// Creates an iterator with the same range, but stepping by the + /// given amount at each iteration. + /// + /// The resulting iterator handles overflow by stopping. + /// + /// # Examples + /// + /// ``` + /// # #![feature(step_by, core)] + /// for i in (0..10).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints: + /// + /// ```text + /// 0 + /// 2 + /// 4 + /// 6 + /// 8 + /// ``` + #[unstable(feature = "step_by", reason = "recent addition")] + pub fn step_by(self, by: A) -> StepBy { + StepBy { + step_by: by, + range: self + } + } +} + /// An infinite iterator starting at `start` and advancing by `step` with each /// iteration -#[derive(Clone)] #[unstable(feature = "core", reason = "may be renamed or replaced by range notation adapters")] -pub struct Counter { - /// The current state the counter is at (next value to be yielded) - state: A, - /// The amount that this iterator is stepping by - step: A, -} +#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")] +pub type Counter = StepBy>; -/// Creates a new counter with the specified start/step +/// Deprecated: use `(start..).step_by(step)` instead. #[inline] #[unstable(feature = "core", reason = "may be renamed or replaced by range notation adapters")] +#[deprecated(since = "1.0.0-beta", reason = "use (start..).step_by(step) instead")] +#[allow(deprecated)] pub fn count(start: A, step: A) -> Counter { - Counter{state: start, step: step} + StepBy { + range: RangeFrom { start: start }, + step_by: step, + } } #[stable(feature = "rust1", since = "1.0.0")] -impl + Clone> Iterator for Counter { +impl + Clone> Iterator for StepBy> { type Item = A; #[inline] fn next(&mut self) -> Option { - let result = self.state.clone(); - self.state = self.state.clone() + self.step.clone(); + let result = self.range.start.clone(); + self.range.start = result.clone() + self.step_by.clone(); Some(result) } @@ -2404,31 +2471,22 @@ impl + Clone> Iterator for Counter { } /// An iterator over the range [start, stop) +#[allow(deprecated)] #[derive(Clone)] #[unstable(feature = "core", reason = "will be replaced by range notation")] +#[deprecated(since = "1.0.0-beta", reason = "use range notation")] pub struct Range { state: A, stop: A, one: A, } -/// Returns an iterator over the given range [start, stop) (that is, starting -/// at start (inclusive), and ending at stop (exclusive)). -/// -/// # Examples -/// -/// ``` -/// let array = [0, 1, 2, 3, 4]; -/// -/// for i in range(0, 5) { -/// println!("{}", i); -/// assert_eq!(i, array[i]); -/// } -/// ``` +/// Deprecated: use `(start..stop)` instead. #[inline] -#[unstable(feature = "core", - reason = "will be replaced by range notation")] +#[unstable(feature = "core", reason = "will be replaced by range notation")] +#[deprecated(since = "1.0.0-beta", reason = "use (start..stop) instead")] +#[allow(deprecated)] pub fn range(start: A, stop: A) -> Range { Range { state: start, @@ -2440,6 +2498,8 @@ pub fn range(start: A, stop: A) -> Range { // FIXME: #10414: Unfortunate type bound #[unstable(feature = "core", reason = "will be replaced by range notation")] +#[deprecated(since = "1.0.0-beta", reason = "use range notation")] +#[allow(deprecated)] impl Iterator for Range { type Item = A; @@ -2491,6 +2551,8 @@ impl Iterator for Range { /// the direction it is consumed. #[unstable(feature = "core", reason = "will be replaced by range notation")] +#[deprecated(since = "1.0.0-beta", reason = "use range notation")] +#[allow(deprecated)] impl DoubleEndedIterator for Range { #[inline] fn next_back(&mut self) -> Option { @@ -2507,6 +2569,7 @@ impl DoubleEndedIterator for Range { #[derive(Clone)] #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] +#[allow(deprecated)] pub struct RangeInclusive { range: Range, done: bool, @@ -2516,6 +2579,7 @@ pub struct RangeInclusive { #[inline] #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] +#[allow(deprecated)] pub fn range_inclusive(start: A, stop: A) -> RangeInclusive { RangeInclusive { range: range(start, stop), @@ -2525,6 +2589,7 @@ pub fn range_inclusive(start: A, stop: A) -> RangeInclusive { #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] +#[allow(deprecated)] impl Iterator for RangeInclusive { type Item = A; @@ -2561,6 +2626,7 @@ impl Iterator for RangeInclusive { #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] +#[allow(deprecated)] impl DoubleEndedIterator for RangeInclusive { #[inline] fn next_back(&mut self) -> Option { @@ -2578,61 +2644,39 @@ impl DoubleEndedIterator for RangeInclusive { } /// An iterator over the range [start, stop) by `step`. It handles overflow by stopping. -#[derive(Clone)] #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] -pub struct RangeStep { - state: A, - stop: A, - step: A, - rev: bool, -} +#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")] +pub type RangeStep = StepBy>; -/// Return an iterator over the range [start, stop) by `step`. -/// -/// It handles overflow by stopping. -/// -/// # Examples -/// -/// ``` -/// use std::iter::range_step; -/// -/// for i in range_step(0, 10, 2) { -/// println!("{}", i); -/// } -/// ``` -/// -/// This prints: -/// -/// ```text -/// 0 -/// 2 -/// 4 -/// 6 -/// 8 -/// ``` +/// Deprecated: use `(start..stop).step_by(step)` instead. #[inline] #[unstable(feature = "core", reason = "likely to be replaced by range notation and adapters")] +#[deprecated(since = "1.0.0-beta", + reason = "use `(start..stop).step_by(step)` instead")] +#[allow(deprecated)] pub fn range_step(start: A, stop: A, step: A) -> RangeStep { - let rev = step < Int::zero(); - RangeStep{state: start, stop: stop, step: step, rev: rev} + StepBy { + step_by: step, + range: ::ops::Range { start: start, end: stop }, + } } -#[unstable(feature = "core", - reason = "likely to be replaced by range notation and adapters")] -impl Iterator for RangeStep { +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for StepBy> { type Item = A; #[inline] fn next(&mut self) -> Option { - if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) { - let result = self.state; - match self.state.checked_add(self.step) { - Some(x) => self.state = x, - None => self.state = self.stop.clone() + let rev = self.step_by < Int::zero(); + let start = self.range.start; + if (rev && start > self.range.end) || (!rev && start < self.range.end) { + match start.checked_add(self.step_by) { + Some(x) => self.range.start = x, + None => self.range.start = self.range.end.clone() } - Some(result) + Some(start) } else { None } diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index f4b1a0633de5c..6c79233da68f1 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -29,6 +29,7 @@ pub use marker::{Copy, Send, Sized, Sync}; pub use ops::{Drop, Fn, FnMut, FnOnce}; // Reexported functions +#[allow(deprecated)] pub use iter::range; pub use mem::drop; diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 0f4e7fcdda57b..52cc2519addaa 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -775,12 +775,12 @@ fn test_range_inclusive() { #[test] fn test_range_step() { - assert_eq!(range_step(0, 20, 5).collect::>(), [0, 5, 10, 15]); - assert_eq!(range_step(20, 0, -5).collect::>(), [20, 15, 10, 5]); - assert_eq!(range_step(20, 0, -6).collect::>(), [20, 14, 8, 2]); - assert_eq!(range_step(200, 255, 50).collect::>(), [200, 250]); - assert_eq!(range_step(200, -5, 1).collect::>(), []); - assert_eq!(range_step(200, 200, 1).collect::>(), []); + assert_eq!((0..20).step_by(5).collect::>(), [0, 5, 10, 15]); + assert_eq!((20..0).step_by(-5).collect::>(), [20, 15, 10, 5]); + assert_eq!((20..0).step_by(-6).collect::>(), [20, 14, 8, 2]); + assert_eq!((200..255).step_by(50).collect::>(), [200, 250]); + assert_eq!((200..-5).step_by(1).collect::>(), []); + assert_eq!((200..200).step_by(1).collect::>(), []); } #[test] diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index 42e830ae4ca4b..79b176a4ffdcb 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -17,8 +17,6 @@ //! internally. The `IndependentSample` trait is for generating values //! that do not need to record state. -#![unstable(feature = "rand")] - use core::prelude::*; use core::num::{Float, Int}; use core::marker::PhantomData; diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index be94a73df37ba..9add236d54b18 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -154,7 +154,7 @@ pub trait Combine<'tcx> : Sized { b_tys.len()))); } - range(0, a_tys.len()).map(|i| { + (0.. a_tys.len()).map(|i| { let a_ty = a_tys[i]; let b_ty = b_tys[i]; let v = variances.map_or(ty::Invariant, |v| v[i]); diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 77338dddefa04..99d24a6013078 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -48,6 +48,7 @@ #![feature(path_ext)] #![feature(std_misc)] #![feature(path_relative_from)] +#![feature(step_by)] extern crate syntax; extern crate serialize; diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 467b7c1ca3819..5aae0e9dbdcf0 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -48,7 +48,6 @@ use std::fmt; use std::hash::{Hash, SipHasher, Hasher}; -use std::iter::range_step; use syntax::ast; use syntax::visit; @@ -103,7 +102,7 @@ impl Svh { let hash = state.finish(); return Svh { - hash: range_step(0, 64, 4).map(|i| hex(hash >> i)).collect() + hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect() }; fn hex(b: u64) -> char { diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index db9966e05487d..219f48f78dc46 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -21,7 +21,6 @@ use libc; use flate; use std::ffi::CString; -use std::iter; use std::mem; use std::num::Int; @@ -62,7 +61,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, let file = path.file_name().unwrap().to_str().unwrap(); let file = &file[3..file.len() - 5]; // chop off lib/.rlib debug!("reading {}", file); - for i in iter::count(0, 1) { + for i in 0.. { let bc_encoded = time(sess.time_passes(), &format!("check for {}.{}.bytecode.deflate", name, i), (), @@ -213,4 +212,3 @@ fn read_from_le_bytes(bytes: &[u8], position_in_bytes: uint) -> T { Int::from_le(data) } - diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 8b275d1bc4ab7..93215090d9562 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -16,8 +16,8 @@ use prelude::v1::*; +use ops::Range; use mem; -use iter::Range; /// Extension methods for ASCII-subset only operations on owned strings #[unstable(feature = "std_misc", @@ -270,7 +270,7 @@ pub fn escape_default(c: u8) -> EscapeDefault { _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4), }; - return EscapeDefault { range: range(0, len), data: data }; + return EscapeDefault { range: (0.. len), data: data }; fn hexify(b: u8) -> u8 { match b { diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index d699886e57747..c502a94ba691d 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -359,7 +359,7 @@ impl fmt::Display for Ipv6Addr { let mut cur_span_len = 0; let mut cur_span_at = 0; - for i in range(0, 8) { + for i in 0..8 { if segments[i] == 0 { if cur_span_len == 0 { cur_span_at = i; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 53882c7b83372..d09e01a304b12 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -586,7 +586,6 @@ pub fn get_exit_status() -> int { unsafe fn load_argc_and_argv(argc: int, argv: *const *const c_char) -> Vec> { use ffi::CStr; - use iter::range; (0..argc).map(|i| { CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec() diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index 60e1354482c8f..31aac333859cd 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -57,6 +57,7 @@ // NB: remove when I/O reform lands #[doc(no_inline)] pub use old_io::{Buffer, Writer, Reader, Seek, BufferPrelude}; // NB: remove when range syntax lands +#[allow(deprecated)] #[doc(no_inline)] pub use iter::range; #[doc(no_inline)] pub use num::wrapping::{Wrapping, WrappingOps}; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 3266da5eb31cb..a939f5c89eb93 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -286,7 +286,7 @@ pub fn args() -> Args { let vec = unsafe { let (argc, argv) = (*_NSGetArgc() as isize, *_NSGetArgv() as *const *const c_char); - range(0, argc as isize).map(|i| { + (0.. argc as isize).map(|i| { let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec(); OsStringExt::from_vec(bytes) }).collect::>() diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ea1c17055141a..f2ada490fad78 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -77,7 +77,6 @@ use owned_slice::OwnedSlice; use std::collections::HashSet; use std::io::prelude::*; -use std::iter; use std::mem; use std::num::Float; use std::path::{Path, PathBuf}; @@ -749,7 +748,7 @@ impl<'a> Parser<'a> { // would encounter a `>` and stop. This lets the parser handle trailing // commas in generic parameters, because it can stop either after // parsing a type or after parsing a comma. - for i in iter::count(0, 1) { + for i in 0.. { if self.check(&token::Gt) || self.token == token::BinOp(token::Shr) || self.token == token::Ge