about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-07-03 14:33:55 -0700
committerGitHub <noreply@github.com>2016-07-03 14:33:55 -0700
commit696b703b5a58816bb0e549ac332a98fa7e635949 (patch)
tree48518dc8a017b2d66d68fa742972779c28641ade /src/libcore
parenteebfcb8bf48351f13b19c2faf0b9aa2f152234e4 (diff)
parent3016626c3aa4bc44807e54a8ba8b9e367ff566f5 (diff)
downloadrust-696b703b5a58816bb0e549ac332a98fa7e635949.tar.gz
rust-696b703b5a58816bb0e549ac332a98fa7e635949.zip
Auto merge of #34530 - alexcrichton:stabilize-1.11, r=aturon
std: Stabilize APIs for the 1.11.0 release

Although the set of APIs being stabilized this release is relatively small, the
trains keep going! Listed below are the APIs in the standard library which have
either transitioned from unstable to stable or those from unstable to
deprecated.

Stable

* `BTreeMap::{append, split_off}`
* `BTreeSet::{append, split_off}`
* `Cell::get_mut`
* `RefCell::get_mut`
* `BinaryHeap::append`
* `{f32, f64}::{to_degrees, to_radians}` - libcore stabilizations mirroring past
  libstd stabilizations
* `Iterator::sum`
* `Iterator::product`

Deprecated

* `{f32, f64}::next_after`
* `{f32, f64}::integer_decode`
* `{f32, f64}::ldexp`
* `{f32, f64}::frexp`
* `num::One`
* `num::Zero`

Added APIs (all unstable)

* `iter::Sum`
* `iter::Product`
* `iter::Step` - a few methods were added to accomodate deprecation of One/Zero

Removed APIs

* `From<Range<T>> for RangeInclusive<T>` - everything about `RangeInclusive` is
  unstable

Closes #27739
Closes #27752
Closes #32526
Closes #33444
Closes #34152
cc #34529 (new tracking issue)
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/cell.rs4
-rw-r--r--src/libcore/iter/iterator.rs50
-rw-r--r--src/libcore/iter/mod.rs5
-rw-r--r--src/libcore/iter/range.rs169
-rw-r--r--src/libcore/iter/traits.rs101
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/num/dec2flt/algorithm.rs2
-rw-r--r--src/libcore/num/dec2flt/mod.rs14
-rw-r--r--src/libcore/num/dec2flt/rawfp.rs35
-rw-r--r--src/libcore/num/f32.rs8
-rw-r--r--src/libcore/num/f64.rs8
-rw-r--r--src/libcore/num/flt2dec/decoder.rs9
-rw-r--r--src/libcore/num/mod.rs48
-rw-r--r--src/libcore/ops.rs24
14 files changed, 362 insertions, 117 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 2700f016751..9435be3b012 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -238,7 +238,7 @@ impl<T:Copy> Cell<T> {
     /// This call borrows `Cell` mutably (at compile-time) which guarantees
     /// that we possess the only reference.
     #[inline]
-    #[unstable(feature = "cell_get_mut", issue = "33444")]
+    #[stable(feature = "cell_get_mut", since = "1.11.0")]
     pub fn get_mut(&mut self) -> &mut T {
         unsafe {
             &mut *self.value.get()
@@ -509,7 +509,7 @@ impl<T: ?Sized> RefCell<T> {
     /// This call borrows `RefCell` mutably (at compile-time) so there is no
     /// need for dynamic checks.
     #[inline]
-    #[unstable(feature = "cell_get_mut", issue="33444")]
+    #[stable(feature = "cell_get_mut", since = "1.11.0")]
     pub fn get_mut(&mut self) -> &mut T {
         unsafe {
             &mut *self.value.get()
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 6f5bb2747df..6b01ccaceea 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -11,18 +11,16 @@
 use clone::Clone;
 use cmp::{Ord, PartialOrd, PartialEq, Ordering};
 use default::Default;
-use num::{Zero, One};
-use ops::{Add, FnMut, Mul};
+use ops::FnMut;
 use option::Option::{self, Some, None};
 use marker::Sized;
 
-use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse,
-            Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev,
-            Zip};
+use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse};
+use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev};
+use super::{Zip, Sum, Product};
 use super::ChainState;
-use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator,
-            IntoIterator};
-use super::ZipImpl;
+use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator};
+use super::{IntoIterator, ZipImpl};
 
 fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 
@@ -1820,36 +1818,41 @@ pub trait Iterator {
     ///
     /// An empty iterator returns the zero value of the type.
     ///
+    /// # Panics
+    ///
+    /// When calling `sum` and a primitive integer type is being returned, this
+    /// method will panic if the computation overflows.
+    ///
     /// # Examples
     ///
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_arith)]
-    ///
     /// let a = [1, 2, 3];
     /// let sum: i32 = a.iter().sum();
     ///
     /// assert_eq!(sum, 6);
     /// ```
-    #[unstable(feature = "iter_arith", reason = "bounds recently changed",
-               issue = "27739")]
-    fn sum<S>(self) -> S where
-        S: Add<Self::Item, Output=S> + Zero,
-        Self: Sized,
+    #[stable(feature = "iter_arith", since = "1.11.0")]
+    fn sum<S>(self) -> S
+        where Self: Sized,
+              S: Sum<Self::Item>,
     {
-        self.fold(Zero::zero(), |s, e| s + e)
+        Sum::sum(self)
     }
 
     /// Iterates over the entire iterator, multiplying all the elements
     ///
     /// An empty iterator returns the one value of the type.
     ///
+    /// # Panics
+    ///
+    /// When calling `product` and a primitive integer type is being returned,
+    /// this method will panic if the computation overflows.
+    ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(iter_arith)]
-    ///
     /// fn factorial(n: u32) -> u32 {
     ///     (1..).take_while(|&i| i <= n).product()
     /// }
@@ -1857,13 +1860,12 @@ pub trait Iterator {
     /// assert_eq!(factorial(1), 1);
     /// assert_eq!(factorial(5), 120);
     /// ```
-    #[unstable(feature="iter_arith", reason = "bounds recently changed",
-               issue = "27739")]
-    fn product<P>(self) -> P where
-        P: Mul<Self::Item, Output=P> + One,
-        Self: Sized,
+    #[stable(feature = "iter_arith", since = "1.11.0")]
+    fn product<P>(self) -> P
+        where Self: Sized,
+              P: Product<Self::Item>,
     {
-        self.fold(One::one(), |p, e| p * e)
+        Product::product(self)
     }
 
     /// Lexicographically compares the elements of this `Iterator` with those
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index b866655bbd5..3ebab266e2f 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -327,8 +327,9 @@ pub use self::sources::{Empty, empty};
 pub use self::sources::{Once, once};
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend,
-                       ExactSizeIterator};
+pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::traits::{ExactSizeIterator, Sum, Product};
 
 mod iterator;
 mod range;
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 08143567bea..c234ef21db6 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -11,7 +11,6 @@
 use clone::Clone;
 use cmp::PartialOrd;
 use mem;
-use num::{Zero, One};
 use ops::{self, Add, Sub};
 use option::Option::{self, Some, None};
 use marker::Sized;
@@ -36,6 +35,24 @@ pub trait Step: PartialOrd + Sized {
     /// Returns `None` if it is not possible to calculate `steps_between`
     /// without overflow.
     fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
+
+    /// Same as `steps_between`, but with a `by` of 1
+    fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize>;
+
+    /// Tests whether this step is negative or not (going backwards)
+    fn is_negative(&self) -> bool;
+
+    /// Replaces this step with `1`, returning itself
+    fn replace_one(&mut self) -> Self;
+
+    /// Replaces this step with `0`, returning itself
+    fn replace_zero(&mut self) -> Self;
+
+    /// Adds one to this step, returning the result
+    fn add_one(&self) -> Self;
+
+    /// Subtracts one to this step, returning the result
+    fn sub_one(&self) -> Self;
 }
 
 macro_rules! step_impl_unsigned {
@@ -65,6 +82,36 @@ macro_rules! step_impl_unsigned {
                     Some(0)
                 }
             }
+
+            #[inline]
+            fn is_negative(&self) -> bool {
+                false
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -106,6 +153,36 @@ macro_rules! step_impl_signed {
                     Some(diff / by_u)
                 }
             }
+
+            #[inline]
+            fn is_negative(&self) -> bool {
+                *self < 0
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -124,6 +201,37 @@ macro_rules! step_impl_no_between {
             fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
                 None
             }
+
+            #[inline]
+            #[allow(unused_comparisons)]
+            fn is_negative(&self) -> bool {
+                *self < 0
+            }
+
+            #[inline]
+            fn replace_one(&mut self) -> Self {
+                mem::replace(self, 0)
+            }
+
+            #[inline]
+            fn replace_zero(&mut self) -> Self {
+                mem::replace(self, 1)
+            }
+
+            #[inline]
+            fn add_one(&self) -> Self {
+                *self + 1
+            }
+
+            #[inline]
+            fn sub_one(&self) -> Self {
+                *self - 1
+            }
+
+            #[inline]
+            fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
+                Self::steps_between(start, end, &1)
+            }
         }
     )*)
 }
@@ -269,12 +377,12 @@ impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
+impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let rev = self.step_by < A::zero();
+        let rev = self.step_by.is_negative();
         if (rev && self.range.start > self.range.end) ||
            (!rev && self.range.start < self.range.end)
         {
@@ -308,7 +416,7 @@ impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
 #[unstable(feature = "inclusive_range",
            reason = "recently added, follows RFC",
            issue = "28237")]
-impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
+impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
     type Item = A;
 
     #[inline]
@@ -322,8 +430,7 @@ impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
             Empty { .. } => return None, // empty iterators yield no values
 
             NonEmpty { ref mut start, ref mut end } => {
-                let zero = A::zero();
-                let rev = self.step_by < zero;
+                let rev = self.step_by.is_negative();
 
                 // march start towards (maybe past!) end and yield the old value
                 if (rev && start >= end) ||
@@ -342,7 +449,7 @@ impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
                     }
                 } else {
                     // found range in inconsistent state (start at or past end), so become empty
-                    (Some(mem::replace(end, zero)), None)
+                    (Some(end.replace_zero()), None)
                 }
             }
         };
@@ -386,7 +493,7 @@ macro_rules! range_exact_iter_impl {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One> Iterator for ops::Range<A> where
+impl<A: Step> Iterator for ops::Range<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
@@ -394,7 +501,7 @@ impl<A: Step + One> Iterator for ops::Range<A> where
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.start < self.end {
-            let mut n = &self.start + &A::one();
+            let mut n = self.start.add_one();
             mem::swap(&mut n, &mut self.start);
             Some(n)
         } else {
@@ -404,7 +511,7 @@ impl<A: Step + One> Iterator for ops::Range<A> where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        match Step::steps_between(&self.start, &self.end, &A::one()) {
+        match Step::steps_between_by_one(&self.start, &self.end) {
             Some(hint) => (hint, Some(hint)),
             None => (0, None)
         }
@@ -416,14 +523,14 @@ impl<A: Step + One> Iterator for ops::Range<A> where
 range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
+impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
     for<'a> &'a A: Add<&'a A, Output = A>,
     for<'a> &'a A: Sub<&'a A, Output = A>
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         if self.start < self.end {
-            self.end = &self.end - &A::one();
+            self.end = self.end.sub_one();
             Some(self.end.clone())
         } else {
             None
@@ -432,21 +539,21 @@ impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Step + One> Iterator for ops::RangeFrom<A> where
+impl<A: Step> Iterator for ops::RangeFrom<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let mut n = &self.start + &A::one();
+        let mut n = self.start.add_one();
         mem::swap(&mut n, &mut self.start);
         Some(n)
     }
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<A: Step + One> Iterator for ops::RangeInclusive<A> where
+impl<A: Step> Iterator for ops::RangeInclusive<A> where
     for<'a> &'a A: Add<&'a A, Output = A>
 {
     type Item = A;
@@ -463,23 +570,22 @@ impl<A: Step + One> Iterator for ops::RangeInclusive<A> where
 
             NonEmpty { ref mut start, ref mut end } => {
                 if start == end {
-                    (Some(mem::replace(end, A::one())), Some(mem::replace(start, A::one())))
+                    (Some(end.replace_one()), Some(start.replace_one()))
                 } else if start < end {
-                    let one = A::one();
-                    let mut n = &*start + &one;
+                    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 -- use the previously
-                    // created A::one() as a dummy value
+                    // 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(mem::replace(end, one)) } else { None },
+                    (if n == *end { Some(end.replace_one()) } else { None },
                     // ^ are we done yet?
                     Some(n)) // < the value to output
                 } else {
-                    (Some(mem::replace(start, A::one())), None)
+                    (Some(start.replace_one()), None)
                 }
             }
         };
@@ -500,7 +606,7 @@ impl<A: Step + One> Iterator for ops::RangeInclusive<A> where
             Empty { .. } => (0, Some(0)),
 
             NonEmpty { ref start, ref end } =>
-                match Step::steps_between(start, end, &A::one()) {
+                match Step::steps_between_by_one(start, end) {
                     Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
                     None => (0, None),
                 }
@@ -509,7 +615,7 @@ impl<A: Step + One> Iterator for ops::RangeInclusive<A> where
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<A: Step + One> DoubleEndedIterator for ops::RangeInclusive<A> where
+impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
     for<'a> &'a A: Add<&'a A, Output = A>,
     for<'a> &'a A: Sub<&'a A, Output = A>
 {
@@ -524,16 +630,15 @@ impl<A: Step + One> DoubleEndedIterator for ops::RangeInclusive<A> where
 
             NonEmpty { ref mut start, ref mut end } => {
                 if start == end {
-                    (Some(mem::replace(start, A::one())), Some(mem::replace(end, A::one())))
+                    (Some(start.replace_one()), Some(end.replace_one()))
                 } else if start < end {
-                    let one = A::one();
-                    let mut n = &*end - &one;
+                    let mut n = end.sub_one();
                     mem::swap(&mut n, end);
 
-                    (if n == *start { Some(mem::replace(start, one)) } else { None },
+                    (if n == *start { Some(start.replace_one()) } else { None },
                      Some(n))
                 } else {
-                    (Some(mem::replace(end, A::one())), None)
+                    (Some(end.replace_one()), None)
                 }
             }
         };
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 67503984450..3549bd6a3bc 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -524,3 +524,104 @@ pub trait ExactSizeIterator: Iterator {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {}
 
+/// Trait to represent types that can be created by summing up an iterator.
+///
+/// This trait is used to implement the `sum` method on iterators. Types which
+/// implement the trait can be generated by the `sum` method. Like
+/// `FromIterator` this trait should rarely be called directly and instead
+/// interacted with through `Iterator::sum`.
+#[unstable(feature = "iter_arith_traits", issue = "34529")]
+pub trait Sum<A = Self>: Sized {
+    /// Method which takes an iterator and generates `Self` from the elements by
+    /// "summing up" the items.
+    fn sum<I: Iterator<Item=A>>(iter: I) -> Self;
+}
+
+/// Trait to represent types that can be created by multiplying elements of an
+/// iterator.
+///
+/// This trait is used to implement the `product` method on iterators. Types
+/// which implement the trait can be generated by the `product` method. Like
+/// `FromIterator` this trait should rarely be called directly and instead
+/// interacted with through `Iterator::product`.
+#[unstable(feature = "iter_arith_traits", issue = "34529")]
+pub trait Product<A = Self>: Sized {
+    /// Method which takes an iterator and generates `Self` from the elements by
+    /// multiplying the items.
+    fn product<I: Iterator<Item=A>>(iter: I) -> Self;
+}
+
+macro_rules! integer_sum_product {
+    ($($a:ident)*) => ($(
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Sum for $a {
+            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(0, |a, b| {
+                    a.checked_add(b).expect("overflow in sum")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Product for $a {
+            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(1, |a, b| {
+                    a.checked_mul(b).expect("overflow in product")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Sum<&'a $a> for $a {
+            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(0, |a, b| {
+                    a.checked_add(*b).expect("overflow in sum")
+                })
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Product<&'a $a> for $a {
+            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(1, |a, b| {
+                    a.checked_mul(*b).expect("overflow in product")
+                })
+            }
+        }
+    )*)
+}
+
+macro_rules! float_sum_product {
+    ($($a:ident)*) => ($(
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Sum for $a {
+            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(0.0, |a, b| a + b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl Product for $a {
+            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+                iter.fold(1.0, |a, b| a * b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Sum<&'a $a> for $a {
+            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(0.0, |a, b| a + *b)
+            }
+        }
+
+        #[unstable(feature = "iter_arith_traits", issue = "34529")]
+        impl<'a> Product<&'a $a> for $a {
+            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+                iter.fold(1.0, |a, b| a * *b)
+            }
+        }
+    )*)
+}
+
+integer_sum_product! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+float_sum_product! { f32 f64 }
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index db73f4759a5..e849369d647 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -59,6 +59,8 @@
 #![deny(missing_debug_implementations)]
 #![cfg_attr(not(stage0), deny(warnings))]
 
+#![cfg_attr(stage0, allow(unused_attributes))]
+
 #![feature(allow_internal_unstable)]
 #![feature(asm)]
 #![feature(associated_type_defaults)]
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index c7af46a1e4f..4761727cec0 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -321,7 +321,7 @@ pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T {
             return underflow(x, v, rem);
         }
         if k > T::max_exp_int() {
-            return T::infinity();
+            return T::infinity2();
         }
         if x < min_sig {
             u.mul_pow2(1);
diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs
index 022bd84f4c8..ff2d85307b1 100644
--- a/src/libcore/num/dec2flt/mod.rs
+++ b/src/libcore/num/dec2flt/mod.rs
@@ -215,11 +215,11 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
     let (sign, s) = extract_sign(s);
     let flt = match parse_decimal(s) {
         ParseResult::Valid(decimal) => convert(decimal)?,
-        ParseResult::ShortcutToInf => T::infinity(),
-        ParseResult::ShortcutToZero => T::zero(),
+        ParseResult::ShortcutToInf => T::infinity2(),
+        ParseResult::ShortcutToZero => T::zero2(),
         ParseResult::Invalid => match s {
-            "inf" => T::infinity(),
-            "NaN" => T::nan(),
+            "inf" => T::infinity2(),
+            "NaN" => T::nan2(),
             _ => { return Err(pfe_invalid()); }
         }
     };
@@ -316,7 +316,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
 fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
     // There were zeros but they were stripped by simplify()
     if decimal.integral.is_empty() && decimal.fractional.is_empty() {
-        return Some(T::zero());
+        return Some(T::zero2());
     }
     // This is a crude approximation of ceil(log10(the real value)). We don't need to worry too
     // much about overflow here because the input length is tiny (at least compared to 2^64) and
@@ -324,9 +324,9 @@ fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
     // (which is still 10^19 short of 2^64).
     let max_place = decimal.exp + decimal.integral.len() as i64;
     if max_place > T::inf_cutoff() {
-        return Some(T::infinity());
+        return Some(T::infinity2());
     } else if max_place < T::zero_cutoff() {
-        return Some(T::zero());
+        return Some(T::zero2());
     }
     None
 }
diff --git a/src/libcore/num/dec2flt/rawfp.rs b/src/libcore/num/dec2flt/rawfp.rs
index 2099c6a7baa..68e4dc4b359 100644
--- a/src/libcore/num/dec2flt/rawfp.rs
+++ b/src/libcore/num/dec2flt/rawfp.rs
@@ -61,6 +61,27 @@ impl Unpacked {
 pub trait RawFloat : Float + Copy + Debug + LowerExp
                     + Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self>
 {
+    // suffix of "2" because Float::infinity is deprecated
+    #[allow(deprecated)]
+    fn infinity2() -> Self {
+        Float::infinity()
+    }
+
+    // suffix of "2" because Float::nan is deprecated
+    #[allow(deprecated)]
+    fn nan2() -> Self {
+        Float::nan()
+    }
+
+    // suffix of "2" because Float::zero is deprecated
+    fn zero2() -> Self;
+
+    // suffix of "2" because Float::integer_decode is deprecated
+    #[allow(deprecated)]
+    fn integer_decode2(self) -> (u64, i16, i8) {
+        Float::integer_decode(self)
+    }
+
     /// Get the raw binary representation of the float.
     fn transmute(self) -> u64;
 
@@ -146,6 +167,10 @@ pub trait RawFloat : Float + Copy + Debug + LowerExp
 }
 
 impl RawFloat for f32 {
+    fn zero2() -> Self {
+        0.0
+    }
+
     fn sig_bits() -> u8 {
         24
     }
@@ -169,7 +194,7 @@ impl RawFloat for f32 {
     }
 
     fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
+        let (sig, exp, _sig) = self.integer_decode2();
         Unpacked::new(sig, exp)
     }
 
@@ -198,6 +223,10 @@ impl RawFloat for f32 {
 
 
 impl RawFloat for f64 {
+    fn zero2() -> Self {
+        0.0
+    }
+
     fn sig_bits() -> u8 {
         53
     }
@@ -220,7 +249,7 @@ impl RawFloat for f64 {
     }
 
     fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
+        let (sig, exp, _sig) = self.integer_decode2();
         Unpacked::new(sig, exp)
     }
 
@@ -351,7 +380,7 @@ pub fn prev_float<T: RawFloat>(x: T) -> T {
 pub fn next_float<T: RawFloat>(x: T) -> T {
     match x.classify() {
         Nan => panic!("next_float: argument is NaN"),
-        Infinite => T::infinity(),
+        Infinite => T::infinity2(),
         // This seems too good to be true, but it works.
         // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
         // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index c24eaa3eabc..79e1462eaa1 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -168,7 +168,7 @@ impl Float for f32 {
     /// Returns `true` if the number is infinite.
     #[inline]
     fn is_infinite(self) -> bool {
-        self == Float::infinity() || self == Float::neg_infinity()
+        self == INFINITY || self == NEG_INFINITY
     }
 
     /// Returns `true` if the number is neither infinite or NaN.
@@ -230,7 +230,7 @@ impl Float for f32 {
     #[inline]
     fn signum(self) -> f32 {
         if self.is_nan() {
-            Float::nan()
+            NAN
         } else {
             unsafe { intrinsics::copysignf32(1.0, self) }
         }
@@ -240,14 +240,14 @@ impl Float for f32 {
     /// `Float::infinity()`.
     #[inline]
     fn is_sign_positive(self) -> bool {
-        self > 0.0 || (1.0 / self) == Float::infinity()
+        self > 0.0 || (1.0 / self) == INFINITY
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
     fn is_sign_negative(self) -> bool {
-        self < 0.0 || (1.0 / self) == Float::neg_infinity()
+        self < 0.0 || (1.0 / self) == NEG_INFINITY
     }
 
     /// Returns the reciprocal (multiplicative inverse) of the number.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index beeee809025..35557f61c45 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -168,7 +168,7 @@ impl Float for f64 {
     /// Returns `true` if the number is infinite.
     #[inline]
     fn is_infinite(self) -> bool {
-        self == Float::infinity() || self == Float::neg_infinity()
+        self == INFINITY || self == NEG_INFINITY
     }
 
     /// Returns `true` if the number is neither infinite or NaN.
@@ -230,7 +230,7 @@ impl Float for f64 {
     #[inline]
     fn signum(self) -> f64 {
         if self.is_nan() {
-            Float::nan()
+            NAN
         } else {
             unsafe { intrinsics::copysignf64(1.0, self) }
         }
@@ -240,14 +240,14 @@ impl Float for f64 {
     /// `Float::infinity()`.
     #[inline]
     fn is_sign_positive(self) -> bool {
-        self > 0.0 || (1.0 / self) == Float::infinity()
+        self > 0.0 || (1.0 / self) == INFINITY
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
     fn is_sign_negative(self) -> bool {
-        self < 0.0 || (1.0 / self) == Float::neg_infinity()
+        self < 0.0 || (1.0 / self) == NEG_INFINITY
     }
 
     /// Returns the reciprocal (multiplicative inverse) of the number.
diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs
index 6265691bde9..5420e7bdd2a 100644
--- a/src/libcore/num/flt2dec/decoder.rs
+++ b/src/libcore/num/flt2dec/decoder.rs
@@ -13,7 +13,8 @@
 use prelude::v1::*;
 
 use {f32, f64};
-use num::{Float, FpCategory};
+use num::FpCategory;
+use num::dec2flt::rawfp::RawFloat;
 
 /// Decoded unsigned finite value, such that:
 ///
@@ -52,7 +53,7 @@ pub enum FullDecoded {
 }
 
 /// A floating point type which can be `decode`d.
-pub trait DecodableFloat: Float + Copy {
+pub trait DecodableFloat: RawFloat + Copy {
     /// The minimum positive normalized value.
     fn min_pos_norm_value() -> Self;
 }
@@ -68,7 +69,7 @@ impl DecodableFloat for f64 {
 /// Returns a sign (true when negative) and `FullDecoded` value
 /// from given floating point number.
 pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
-    let (mant, exp, sign) = v.integer_decode();
+    let (mant, exp, sign) = v.integer_decode2();
     let even = (mant & 1) == 0;
     let decoded = match v.classify() {
         FpCategory::Nan => FullDecoded::Nan,
@@ -82,7 +83,7 @@ pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) {
                                           exp: exp, inclusive: even })
         }
         FpCategory::Normal => {
-            let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode();
+            let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode2();
             if mant == minnorm.0 {
                 // neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp)
                 // where maxmant = minnormmant * 2 - 1
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 06398fc094e..0d79398a8f1 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -109,6 +109,8 @@ pub mod diy_float;
 #[unstable(feature = "zero_one",
            reason = "unsure of placement, wants to use associated constants",
            issue = "27739")]
+#[rustc_deprecated(since = "1.11.0", reason = "no longer used for \
+                                               Iterator::sum")]
 pub trait Zero: Sized {
     /// The "zero" (usually, additive identity) for this type.
     fn zero() -> Self;
@@ -121,6 +123,8 @@ pub trait Zero: Sized {
 #[unstable(feature = "zero_one",
            reason = "unsure of placement, wants to use associated constants",
            issue = "27739")]
+#[rustc_deprecated(since = "1.11.0", reason = "no longer used for \
+                                               Iterator::product")]
 pub trait One: Sized {
     /// The "one" (usually, multiplicative identity) for this type.
     fn one() -> Self;
@@ -131,6 +135,7 @@ macro_rules! zero_one_impl {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl Zero for $t {
             #[inline]
             fn zero() -> Self { 0 }
@@ -138,6 +143,7 @@ macro_rules! zero_one_impl {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl One for $t {
             #[inline]
             fn one() -> Self { 1 }
@@ -151,6 +157,7 @@ macro_rules! zero_one_impl_float {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl Zero for $t {
             #[inline]
             fn zero() -> Self { 0.0 }
@@ -158,6 +165,7 @@ macro_rules! zero_one_impl_float {
         #[unstable(feature = "zero_one",
                    reason = "unsure of placement, wants to use associated constants",
                    issue = "27739")]
+        #[allow(deprecated)]
         impl One for $t {
             #[inline]
             fn one() -> Self { 1.0 }
@@ -604,7 +612,7 @@ macro_rules! int_impl {
         pub fn saturating_add(self, other: Self) -> Self {
             match self.checked_add(other) {
                 Some(x) => x,
-                None if other >= Self::zero() => Self::max_value(),
+                None if other >= 0 => Self::max_value(),
                 None => Self::min_value(),
             }
         }
@@ -625,7 +633,7 @@ macro_rules! int_impl {
         pub fn saturating_sub(self, other: Self) -> Self {
             match self.checked_sub(other) {
                 Some(x) => x,
-                None if other >= Self::zero() => Self::min_value(),
+                None if other >= 0 => Self::min_value(),
                 None => Self::max_value(),
             }
         }
@@ -1064,7 +1072,7 @@ macro_rules! int_impl {
         #[rustc_inherit_overflow_checks]
         pub fn pow(self, mut exp: u32) -> Self {
             let mut base = self;
-            let mut acc = Self::one();
+            let mut acc = 1;
 
             while exp > 1 {
                 if (exp & 1) == 1 {
@@ -2092,7 +2100,7 @@ macro_rules! uint_impl {
         #[rustc_inherit_overflow_checks]
         pub fn pow(self, mut exp: u32) -> Self {
             let mut base = self;
-            let mut acc = Self::one();
+            let mut acc = 1;
 
             let mut prev_base = self;
             let mut base_oflo = false;
@@ -2129,8 +2137,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn is_power_of_two(self) -> bool {
-            (self.wrapping_sub(Self::one())) & self == Self::zero() &&
-                !(self == Self::zero())
+            (self.wrapping_sub(1)) & self == 0 && !(self == 0)
         }
 
         /// Returns the smallest power of two greater than or equal to `self`.
@@ -2148,7 +2155,7 @@ macro_rules! uint_impl {
         #[inline]
         pub fn next_power_of_two(self) -> Self {
             let bits = size_of::<Self>() * 8;
-            let one: Self = Self::one();
+            let one: Self = 1;
             one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
         }
 
@@ -2303,26 +2310,44 @@ pub trait Float: Sized {
     /// Returns the NaN value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn nan() -> Self;
     /// Returns the infinite value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn infinity() -> Self;
     /// Returns the negative infinite value.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn neg_infinity() -> Self;
     /// Returns -0.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn neg_zero() -> Self;
     /// Returns 0.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn zero() -> Self;
     /// Returns 1.0.
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn one() -> Self;
 
     /// Returns true if this value is NaN and false otherwise.
@@ -2345,6 +2370,9 @@ pub trait Float: Sized {
     /// Returns the mantissa, exponent and sign as integers, respectively.
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     fn integer_decode(self) -> (u64, i16, i8);
 
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
@@ -2379,12 +2407,10 @@ pub trait Float: Sized {
     fn powi(self, n: i32) -> Self;
 
     /// Convert radians to degrees.
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "deg_rad_conversions", since="1.7.0")]
     fn to_degrees(self) -> Self;
     /// Convert degrees to radians.
-    #[unstable(feature = "float_extras", reason = "desirability is unclear",
-               issue = "27752")]
+    #[stable(feature = "deg_rad_conversions", since="1.7.0")]
     fn to_radians(self) -> Self;
 }
 
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 7258c8a1b6b..7753aae147a 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -69,9 +69,7 @@
 
 use cmp::PartialOrd;
 use fmt;
-use convert::From;
 use marker::{Sized, Unsize};
-use num::One;
 
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
@@ -1494,7 +1492,6 @@ impl fmt::Debug for RangeFull {
 /// # Examples
 ///
 /// ```
-/// #![feature(iter_arith)]
 /// fn main() {
 ///     assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3..6).sum());
@@ -1558,7 +1555,6 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
 /// # Examples
 ///
 /// ```
-/// #![feature(iter_arith)]
 /// fn main() {
 ///     assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
 ///     assert_eq!(2+3+4, (2..).take(3).sum());
@@ -1660,7 +1656,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
 /// # Examples
 ///
 /// ```
-/// #![feature(inclusive_range,inclusive_range_syntax,iter_arith)]
+/// #![feature(inclusive_range,inclusive_range_syntax)]
 /// fn main() {
 ///     assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3...5).sum());
@@ -1714,24 +1710,6 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     }
 }
 
-#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<Idx: PartialOrd + One + Sub<Output=Idx>> From<Range<Idx>> for RangeInclusive<Idx> {
-    fn from(range: Range<Idx>) -> RangeInclusive<Idx> {
-        use self::RangeInclusive::*;
-
-        if range.start < range.end {
-            NonEmpty {
-                start: range.start,
-                end: range.end - Idx::one() // can't underflow because end > start >= MIN
-            }
-        } else {
-            Empty {
-                at: range.start
-            }
-        }
-    }
-}
-
 #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
 impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// # Examples