about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/iter.rs116
-rw-r--r--src/test/compile-fail/range-1.rs5
-rw-r--r--src/test/run-pass/range-type-infer.rs28
3 files changed, 76 insertions, 73 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 751b5959d8b..c782452d4cf 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2797,93 +2797,71 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
     }
 }
 
-macro_rules! range_impl {
+macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::Range<$t> {
-            type Item = $t;
-
+        impl ExactSizeIterator for ::ops::Range<$t> {
             #[inline]
-            fn next(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    let result = self.start;
-                    self.start += 1;
-                    return Some(result);
-                }
-
-                return None;
-            }
-
-            #[inline]
-            fn size_hint(&self) -> (usize, Option<usize>) {
+            fn len(&self) -> usize {
                 debug_assert!(self.end >= self.start);
-                let hint = (self.end - self.start) as usize;
-                (hint, Some(hint))
+                (self.end - self.start) as usize
             }
         }
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl ExactSizeIterator for ::ops::Range<$t> {}
     )*)
 }
 
-macro_rules! range_impl_no_hint {
-    ($($t:ty)*) => ($(
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::Range<$t> {
-            type Item = $t;
-
-            #[inline]
-            fn next(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    let result = self.start;
-                    self.start += 1;
-                    return Some(result);
-                }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> Iterator for ::ops::Range<A> {
+    type Item = A;
 
-                return None;
-            }
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        if self.start < self.end {
+            let result = self.start;
+            self.start = self.start + Int::one();
+            Some(result)
+        } else {
+            None
         }
-    )*)
-}
-
-macro_rules! range_other_impls {
-    ($($t:ty)*) => ($(
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl DoubleEndedIterator for ::ops::Range<$t> {
-            #[inline]
-            fn next_back(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    self.end -= 1;
-                    return Some(self.end);
-                }
+    }
 
-                return None;
-            }
-        }
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        debug_assert!(self.end >= self.start);
+        let hint = (self.end - self.start).to_uint();
+        (hint.unwrap_or(0), hint)
+    }
+}
 
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::RangeFrom<$t> {
-            type Item = $t;
+range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
+#[cfg(target_pointer_width = "64")]
+range_exact_iter_impl!(u64 i64);
 
-            #[inline]
-            fn next(&mut self) -> Option<$t> {
-                let result = self.start;
-                self.start += 1;
-                debug_assert!(result < self.start);
-                return Some(result);
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> DoubleEndedIterator for ::ops::Range<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        if self.start < self.end {
+            self.end = self.end - Int::one();
+            Some(self.end)
+        } else {
+            None
         }
-    )*)
+    }
 }
 
-range_impl!(usize u8 u16 u32 isize i8 i16 i32);
-#[cfg(target_pointer_width = "64")]
-range_impl!(u64 i64);
-#[cfg(target_pointer_width = "32")]
-range_impl_no_hint!(u64 i64);
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> Iterator for ::ops::RangeFrom<A> {
+    type Item = A;
 
-range_other_impls!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        let result = self.start;
+        self.start = self.start + Int::one();
+        debug_assert!(result < self.start);
+        Some(result)
+    }
+}
 
 /// An iterator that repeats an element endlessly
 #[derive(Clone)]
diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs
index 67b203bec19..a8b6e399418 100644
--- a/src/test/compile-fail/range-1.rs
+++ b/src/test/compile-fail/range-1.rs
@@ -17,10 +17,7 @@ pub fn main() {
 
     // Float => does not implement iterator.
     for i in 0f32..42f32 {}
-    //~^ ERROR `core::iter::Iterator` is not implemented for the type `core::ops::Range<f32>`
-    //~^^ ERROR
-    //~^^^ ERROR
-    // FIXME(#21528) not fulfilled obligation error should be reported once, not thrice
+    //~^ ERROR the trait `core::num::Int` is not implemented for the type `f32`
 
     // Unsized type.
     let arr: &[_] = &[1u32, 2, 3];
diff --git a/src/test/run-pass/range-type-infer.rs b/src/test/run-pass/range-type-infer.rs
new file mode 100644
index 00000000000..51945a4677d
--- /dev/null
+++ b/src/test/run-pass/range-type-infer.rs
@@ -0,0 +1,28 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Make sure the type inference for the new range expression work as
+// good as the old one. Check out issue #21672, #21595 and #21649 for
+// more details.
+
+fn main() {
+    let xs = (0..8).map(|i| i == 1u64).collect::<Vec<_>>();
+    assert_eq!(xs[1], true);
+    let xs = (0..8).map(|i| 1u64 == i).collect::<Vec<_>>();
+    assert_eq!(xs[1], true);
+    let xs: Vec<u8> = (0..10).collect();
+    assert_eq!(xs.len(), 10);
+
+    for x in 0..10 { x % 2; }
+    for x in 0..100 { x as f32; }
+
+    let array = [true, false];
+    for i in 0..1 { array[i]; }
+}