diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 140801737bc4c..b9f5c6fcab909 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -825,8 +825,6 @@ impl BinaryHeap { /// Basic usage: /// /// ``` - /// #![feature(binary_heap_append)] - /// /// use std::collections::BinaryHeap; /// /// let v = vec![-10, 1, 2, 3, 3]; @@ -840,9 +838,7 @@ impl BinaryHeap { /// assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]); /// assert!(b.is_empty()); /// ``` - #[unstable(feature = "binary_heap_append", - reason = "needs to be audited", - issue = "32526")] + #[stable(feature = "binary_heap_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { if self.len() < other.len() { swap(self, other); diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 3b775dc2865ee..aea7a1c13a281 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -559,7 +559,6 @@ impl BTreeMap { /// # Examples /// /// ``` - /// #![feature(btree_append)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -583,8 +582,7 @@ impl BTreeMap { /// assert_eq!(a[&4], "e"); /// assert_eq!(a[&5], "f"); /// ``` - #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2", - issue = "34152")] + #[stable(feature = "btree_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { // Do we have to append anything at all? if other.len() == 0 { @@ -914,7 +912,6 @@ impl BTreeMap { /// Basic usage: /// /// ``` - /// #![feature(btree_split_off)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -936,9 +933,7 @@ impl BTreeMap { /// assert_eq!(b[&17], "d"); /// assert_eq!(b[&41], "e"); /// ``` - #[unstable(feature = "btree_split_off", - reason = "recently added as part of collections reform 2", - issue = "34152")] + #[stable(feature = "btree_split_off", since = "1.11.0")] pub fn split_off(&mut self, key: &Q) -> Self where K: Borrow { diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index c47eb0b3fad45..0f885bc2950a6 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -551,7 +551,6 @@ impl BTreeSet { /// # Examples /// /// ``` - /// #![feature(btree_append)] /// use std::collections::BTreeSet; /// /// let mut a = BTreeSet::new(); @@ -575,8 +574,7 @@ impl BTreeSet { /// assert!(a.contains(&4)); /// assert!(a.contains(&5)); /// ``` - #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2", - issue = "34152")] + #[stable(feature = "btree_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { self.map.append(&mut other.map); } @@ -589,7 +587,6 @@ impl BTreeSet { /// Basic usage: /// /// ``` - /// #![feature(btree_split_off)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -611,9 +608,7 @@ impl BTreeSet { /// assert_eq!(b[&17], "d"); /// assert_eq!(b[&41], "e"); /// ``` - #[unstable(feature = "btree_split_off", - reason = "recently added as part of collections reform 2", - issue = "34152")] + #[stable(feature = "btree_split_off", since = "1.11.0")] pub fn split_off(&mut self, key: &Q) -> Self where T: Borrow { BTreeSet { map: self.map.split_off(key) } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7ac01103d61fe..f027d074cb6f0 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -38,7 +38,6 @@ #![feature(fmt_internals)] #![feature(heap_api)] #![feature(inclusive_range)] -#![feature(iter_arith)] #![feature(lang_items)] #![feature(nonzero)] #![feature(pattern)] diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 6161bad7468c6..8ae63808f2740 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -11,18 +11,14 @@ #![deny(warnings)] #![feature(binary_heap_extras)] -#![feature(binary_heap_append)] #![feature(binary_heap_peek_mut)] #![feature(box_syntax)] -#![feature(btree_append)] -#![feature(btree_split_off)] #![feature(btree_range)] #![feature(collections)] #![feature(collections_bound)] #![feature(const_fn)] #![feature(fn_traits)] #![feature(enumset)] -#![feature(iter_arith)] #![feature(linked_list_contains)] #![feature(pattern)] #![feature(rand)] diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 2700f016751dc..9435be3b0124b 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -238,7 +238,7 @@ impl Cell { /// 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 RefCell { /// 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 6f5bb2747df8f..6b01ccaceea2f 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) {} @@ -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(self) -> S where - S: Add + Zero, - Self: Sized, + #[stable(feature = "iter_arith", since = "1.11.0")] + fn sum(self) -> S + where Self: Sized, + S: Sum, { - 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

(self) -> P where - P: Mul + One, - Self: Sized, + #[stable(feature = "iter_arith", since = "1.11.0")] + fn product

(self) -> P + where Self: Sized, + P: Product, { - 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 b866655bbd53d..3ebab266e2ffe 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 08143567beaf3..c234ef21db6d1 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; + + /// Same as `steps_between`, but with a `by` of 1 + fn steps_between_by_one(start: &Self, end: &Self) -> Option; + + /// 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 { + 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 { + 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 { 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 { + Self::steps_between(start, end, &1) + } } )*) } @@ -269,12 +377,12 @@ impl Iterator for StepBy> where } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for StepBy> { +impl Iterator for StepBy> { type Item = A; #[inline] fn next(&mut self) -> Option { - 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 Iterator for StepBy> { #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -impl Iterator for StepBy> { +impl Iterator for StepBy> { type Item = A; #[inline] @@ -322,8 +430,7 @@ impl Iterator for StepBy> { 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 Iterator for StepBy> { } } 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 Iterator for ops::Range where +impl Iterator for ops::Range where for<'a> &'a A: Add<&'a A, Output = A> { type Item = A; @@ -394,7 +501,7 @@ impl Iterator for ops::Range where #[inline] fn next(&mut self) -> Option { 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 Iterator for ops::Range where #[inline] fn size_hint(&self) -> (usize, Option) { - 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 Iterator for ops::Range where range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32); #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for ops::Range where +impl DoubleEndedIterator for ops::Range 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 { 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 DoubleEndedIterator for ops::Range where } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for ops::RangeFrom where +impl Iterator for ops::RangeFrom where for<'a> &'a A: Add<&'a A, Output = A> { type Item = A; #[inline] fn next(&mut self) -> Option { - 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 Iterator for ops::RangeInclusive where +impl Iterator for ops::RangeInclusive where for<'a> &'a A: Add<&'a A, Output = A> { type Item = A; @@ -463,23 +570,22 @@ impl Iterator for ops::RangeInclusive 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 Iterator for ops::RangeInclusive 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 Iterator for ops::RangeInclusive where } #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -impl DoubleEndedIterator for ops::RangeInclusive where +impl DoubleEndedIterator for ops::RangeInclusive where for<'a> &'a A: Add<&'a A, Output = A>, for<'a> &'a A: Sub<&'a A, Output = A> { @@ -524,16 +630,15 @@ impl DoubleEndedIterator for ops::RangeInclusive 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 67503984450a4..3549bd6a3bc68 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: Sized { + /// Method which takes an iterator and generates `Self` from the elements by + /// "summing up" the items. + fn sum>(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: Sized { + /// Method which takes an iterator and generates `Self` from the elements by + /// multiplying the items. + fn product>(iter: I) -> Self; +} + +macro_rules! integer_sum_product { + ($($a:ident)*) => ($( + #[unstable(feature = "iter_arith_traits", issue = "34529")] + impl Sum for $a { + fn sum>(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>(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>(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>(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>(iter: I) -> $a { + iter.fold(0.0, |a, b| a + b) + } + } + + #[unstable(feature = "iter_arith_traits", issue = "34529")] + impl Product for $a { + fn product>(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>(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>(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 db73f4759a5ff..e849369d647c4 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 c7af46a1e4f6b..4761727cec03f 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -321,7 +321,7 @@ pub fn algorithm_m(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 022bd84f4c841..ff2d85307b106 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -215,11 +215,11 @@ fn dec2flt(s: &str) -> Result { 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(decimal: &Decimal) -> Option { // 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(decimal: &Decimal) -> Option { // (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 2099c6a7baa76..68e4dc4b359ef 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 + Div + Neg { + // 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(x: T) -> T { pub fn next_float(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 c24eaa3eabc75..79e1462eaa135 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 beeee80902525..35557f61c4542 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 6265691bde9e9..5420e7bdd2a5a 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(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(v: T) -> (/*negative?*/ bool, FullDecoded) { exp: exp, inclusive: even }) } FpCategory::Normal => { - let minnorm = ::min_pos_norm_value().integer_decode(); + let minnorm = ::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 06398fc094e85..0d79398a8f1d5 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::() * 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 7258c8a1b6b3d..7753aae147a88 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> Range { /// # 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> RangeTo { /// # 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 fmt::Debug for RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -impl> From> for RangeInclusive { - fn from(range: Range) -> RangeInclusive { - 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> RangeInclusive { /// # Examples diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 88d73df937f7e..c6bceab793125 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -19,9 +19,7 @@ #![feature(core_private_diy_float)] #![feature(dec2flt)] #![feature(fixed_size_array)] -#![feature(float_extras)] #![feature(flt2dec)] -#![feature(iter_arith)] #![feature(libc)] #![feature(nonzero)] #![feature(rand)] diff --git a/src/libcoretest/num/dec2flt/rawfp.rs b/src/libcoretest/num/dec2flt/rawfp.rs index 4c0a403e574a3..1a3533317dae6 100644 --- a/src/libcoretest/num/dec2flt/rawfp.rs +++ b/src/libcoretest/num/dec2flt/rawfp.rs @@ -9,9 +9,24 @@ // except according to those terms. use std::f64; +use std::mem; use core::num::diy_float::Fp; use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal}; +fn integer_decode(f: f64) -> (u64, i16, i8) { + let bits: u64 = unsafe { mem::transmute(f) }; + let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; + let mantissa = if exponent == 0 { + (bits & 0xfffffffffffff) << 1 + } else { + (bits & 0xfffffffffffff) | 0x10000000000000 + }; + // Exponent bias + mantissa shift + exponent -= 1023 + 52; + (mantissa, exponent, sign) +} + #[test] fn fp_to_float_half_to_even() { fn is_normalized(sig: u64) -> bool { @@ -21,12 +36,12 @@ fn fp_to_float_half_to_even() { fn conv(sig: u64) -> u64 { // The significands are perfectly in range, so the exponent should not matter - let (m1, e1, _) = fp_to_float::(Fp { f: sig, e: 0 }).integer_decode(); + let (m1, e1, _) = integer_decode(fp_to_float::(Fp { f: sig, e: 0 })); assert_eq!(e1, 0 + 64 - 53); - let (m2, e2, _) = fp_to_float::(Fp { f: sig, e: 55 }).integer_decode(); + let (m2, e2, _) = integer_decode(fp_to_float::(Fp { f: sig, e: 55 })); assert_eq!(e2, 55 + 64 - 53); assert_eq!(m2, m1); - let (m3, e3, _) = fp_to_float::(Fp { f: sig, e: -78 }).integer_decode(); + let (m3, e3, _) = integer_decode(fp_to_float::(Fp { f: sig, e: -78 })); assert_eq!(e3, -78 + 64 - 53); assert_eq!(m3, m2); m3 @@ -65,7 +80,7 @@ const SOME_FLOATS: [f64; 9] = #[test] fn human_f64_roundtrip() { for &x in &SOME_FLOATS { - let (f, e, _) = x.integer_decode(); + let (f, e, _) = integer_decode(x); let fp = Fp { f: f, e: e}; assert_eq!(fp_to_float::(fp), x); } diff --git a/src/libcoretest/num/flt2dec/estimator.rs b/src/libcoretest/num/flt2dec/estimator.rs index 21260c520f623..857aae72c8a5b 100644 --- a/src/libcoretest/num/flt2dec/estimator.rs +++ b/src/libcoretest/num/flt2dec/estimator.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::f64; use core::num::flt2dec::estimator::*; #[test] @@ -54,7 +53,7 @@ fn test_estimate_scaling_factor() { assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309); for i in -1074..972 { - let expected = f64::ldexp(1.0, i).log10().ceil(); + let expected = super::ldexp_f64(1.0, i).log10().ceil(); assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16); } } diff --git a/src/libcoretest/num/flt2dec/mod.rs b/src/libcoretest/num/flt2dec/mod.rs index 1a592f3ad4249..0f4d19e709257 100644 --- a/src/libcoretest/num/flt2dec/mod.rs +++ b/src/libcoretest/num/flt2dec/mod.rs @@ -89,6 +89,17 @@ macro_rules! try_fixed { }) } +fn ldexp_f32(a: f32, b: i32) -> f32 { + ldexp_f64(a as f64, b) as f32 +} + +fn ldexp_f64(a: f64, b: i32) -> f64 { + extern { + fn ldexp(x: f64, n: i32) -> f64; + } + unsafe { ldexp(a, b) } +} + fn check_exact(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16) where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { // use a large enough buffer @@ -237,7 +248,7 @@ pub fn f32_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) // 10^8 * 0.3355443 // 10^8 * 0.33554432 // 10^8 * 0.33554436 - check_shortest!(f(f32::ldexp(1.0, 25)) => b"33554432", 8); + check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8); // 10^39 * 0.340282326356119256160033759537265639424 // 10^39 * 0.34028234663852885981170418348451692544 @@ -252,13 +263,13 @@ pub fn f32_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) // 10^-44 * 0 // 10^-44 * 0.1401298464324817070923729583289916131280... // 10^-44 * 0.2802596928649634141847459166579832262560... - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); check_shortest!(f(minf32) => b"1", -44); } pub fn f32_exact_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); check_exact!(f(0.1f32) => b"100000001490116119384765625 ", 0); check_exact!(f(0.5f32) => b"5 ", 0); @@ -336,7 +347,7 @@ pub fn f64_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) // 10^20 * 0.18446744073709549568 // 10^20 * 0.18446744073709551616 // 10^20 * 0.18446744073709555712 - check_shortest!(f(f64::ldexp(1.0, 64)) => b"18446744073709552", 20); + check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20); // pathological case: high = 10^23 (exact). tie breaking should always prefer that. // 10^24 * 0.099999999999999974834176 @@ -357,13 +368,13 @@ pub fn f64_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) // 10^-323 * 0 // 10^-323 * 0.4940656458412465441765687928682213723650... // 10^-323 * 0.9881312916824930883531375857364427447301... - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); check_shortest!(f(minf64) => b"5", -323); } pub fn f64_exact_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); check_exact!(f(0.1f64) => b"1000000000000000055511151231257827021181", 0); check_exact!(f(0.45f64) => b"4500000000000000111022302462515654042363", 0); @@ -616,7 +627,7 @@ pub fn to_shortest_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, 1, false), format!("34028235{:0>31}.0", "")); assert_eq!(to_string(f, f32::MAX, Minus, 8, false), format!("34028235{:0>31}.00000000", "")); - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); assert_eq!(to_string(f, minf32, Minus, 0, false), format!("0.{:0>44}1", "")); assert_eq!(to_string(f, minf32, Minus, 45, false), format!("0.{:0>44}1", "")); assert_eq!(to_string(f, minf32, Minus, 46, false), format!("0.{:0>44}10", "")); @@ -628,7 +639,7 @@ pub fn to_shortest_str_test(mut f_: F) assert_eq!(to_string(f, f64::MAX, Minus, 8, false), format!("17976931348623157{:0>292}.00000000", "")); - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); assert_eq!(to_string(f, minf64, Minus, 0, false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", "")); @@ -730,7 +741,7 @@ pub fn to_shortest_exp_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38"); assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", "")); - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); assert_eq!(to_string(f, minf32, Minus, ( -4, 16), false), "1e-45"); assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45"); assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", "")); @@ -742,7 +753,7 @@ pub fn to_shortest_exp_str_test(mut f_: F) assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false), "1.7976931348623157e308"); - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); assert_eq!(to_string(f, minf64, Minus, ( -4, 16), false), "5e-324"); assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324"); @@ -874,7 +885,7 @@ pub fn to_exact_exp_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, 64, false), "3.402823466385288598117041834845169254400000000000000000000000000e38"); - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); assert_eq!(to_string(f, minf32, Minus, 1, false), "1e-45"); assert_eq!(to_string(f, minf32, Minus, 2, false), "1.4e-45"); assert_eq!(to_string(f, minf32, Minus, 4, false), "1.401e-45"); @@ -914,7 +925,7 @@ pub fn to_exact_exp_str_test(mut f_: F) 0000000000000000000000000000000000000000000000000000000000000000e308"); // okay, this is becoming tough. fortunately for us, this is almost the worst case. - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); assert_eq!(to_string(f, minf64, Minus, 1, false), "5e-324"); assert_eq!(to_string(f, minf64, Minus, 2, false), "4.9e-324"); assert_eq!(to_string(f, minf64, Minus, 4, false), "4.941e-324"); @@ -1120,7 +1131,7 @@ pub fn to_exact_fixed_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, 2, false), "340282346638528859811704183484516925440.00"); - let minf32 = f32::ldexp(1.0, -149); + let minf32 = ldexp_f32(1.0, -149); assert_eq!(to_string(f, minf32, Minus, 0, false), "0"); assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0"); assert_eq!(to_string(f, minf32, Minus, 2, false), "0.00"); @@ -1152,7 +1163,7 @@ pub fn to_exact_fixed_str_test(mut f_: F) 9440758685084551339423045832369032229481658085593321233482747978\ 26204144723168738177180919299881250404026184124858368.0000000000"); - let minf64 = f64::ldexp(1.0, -1074); + let minf64 = ldexp_f64(1.0, -1074); assert_eq!(to_string(f, minf64, Minus, 0, false), "0"); assert_eq!(to_string(f, minf64, Minus, 1, false), "0.0"); assert_eq!(to_string(f, minf64, Minus, 10, false), "0.0000000000"); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index eb9dd7dfcb36f..48ea953cc1e8b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -30,7 +30,6 @@ #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(enumset)] -#![feature(iter_arith)] #![feature(libc)] #![feature(nonzero)] #![feature(quote)] diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 2da9a55f1fd44..726ba4fc1924f 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -27,7 +27,6 @@ #![feature(staged_api)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] -#![feature(iter_arith)] #![feature(question_mark)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index c369858556d3a..9cb5d8b6ad62a 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -28,7 +28,6 @@ #![feature(const_fn)] #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(iter_arith)] #![feature(libc)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 7ccff7ad3d87c..6239506c2d780 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -76,7 +76,6 @@ This API is completely unstable and subject to change. #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(iter_arith)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 17d412411c048..7a676c041ad89 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -110,6 +110,7 @@ mod cmath { } #[inline] + #[allow(deprecated)] pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float { let (a, b) = f64::frexp(x as f64); *value = b as c_int; @@ -117,6 +118,7 @@ mod cmath { } #[inline] + #[allow(deprecated)] pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float { f64::ldexp(x as f64, n as isize) as c_float } @@ -265,7 +267,11 @@ impl f32 { /// [floating-point]: ../reference.html#machine-types #[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")] #[inline] + #[allow(deprecated)] pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) } @@ -718,6 +724,9 @@ impl f32 { #[unstable(feature = "float_extras", reason = "pending integer conventions", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn ldexp(x: f32, exp: isize) -> f32 { unsafe { cmath::ldexpf(x, exp as c_int) } @@ -747,6 +756,9 @@ impl f32 { #[unstable(feature = "float_extras", reason = "pending integer conventions", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn frexp(self) -> (f32, isize) { unsafe { @@ -773,6 +785,9 @@ impl f32 { #[unstable(feature = "float_extras", reason = "unsure about its place in the world", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn next_after(self, other: f32) -> f32 { unsafe { cmath::nextafterf(self, other) } @@ -1384,6 +1399,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_integer_decode() { assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1)); assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1)); @@ -1711,6 +1727,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_ldexp() { let f1 = 2.0f32.powi(-123); let f2 = 2.0f32.powi(-111); @@ -1731,6 +1748,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_frexp() { let f1 = 2.0f32.powi(-123); let f2 = 2.0f32.powi(-111); @@ -1750,6 +1768,7 @@ mod tests { } #[test] #[cfg_attr(windows, ignore)] // FIXME #8755 + #[allow(deprecated)] fn test_frexp_nowin() { let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 70b7706535ca1..67a1c302483d2 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -209,7 +209,11 @@ impl f64 { /// [floating-point]: ../reference.html#machine-types #[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")] #[inline] + #[allow(deprecated)] pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) } /// Returns the largest integer less than or equal to a number. @@ -613,6 +617,9 @@ impl f64 { #[unstable(feature = "float_extras", reason = "pending integer conventions", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn ldexp(x: f64, exp: isize) -> f64 { unsafe { cmath::ldexp(x, exp as c_int) } @@ -640,6 +647,9 @@ impl f64 { #[unstable(feature = "float_extras", reason = "pending integer conventions", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn frexp(self) -> (f64, isize) { unsafe { @@ -664,6 +674,9 @@ impl f64 { #[unstable(feature = "float_extras", reason = "unsure about its place in the world", issue = "27752")] + #[rustc_deprecated(since = "1.11.0", + reason = "never really came to fruition and easily \ + implementable outside the standard library")] #[inline] pub fn next_after(self, other: f64) -> f64 { unsafe { cmath::nextafter(self, other) } @@ -1277,6 +1290,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_integer_decode() { assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1)); assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1)); @@ -1604,6 +1618,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_ldexp() { let f1 = 2.0f64.powi(-123); let f2 = 2.0f64.powi(-111); @@ -1624,6 +1639,7 @@ mod tests { } #[test] + #[allow(deprecated)] fn test_frexp() { let f1 = 2.0f64.powi(-123); let f2 = 2.0f64.powi(-111); @@ -1643,6 +1659,7 @@ mod tests { } #[test] #[cfg_attr(windows, ignore)] // FIXME #8755 + #[allow(deprecated)] fn test_frexp_nowin() { let inf: f64 = INFINITY; let neg_inf: f64 = NEG_INFINITY; diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index d33df05acf224..20804d62dfab6 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -17,6 +17,7 @@ #![allow(missing_docs)] #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] pub use core::num::{Zero, One}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}; @@ -46,7 +47,6 @@ pub fn test_num(ten: T, two: T) where #[cfg(test)] mod tests { - use super::*; use u8; use u16; use u32; @@ -198,15 +198,14 @@ mod tests { #[test] fn test_pow() { - fn naive_pow + One + Copy>(base: T, exp: usize) -> T { - let one: T = T::one(); + fn naive_pow + Copy>(one: T, base: T, exp: usize) -> T { (0..exp).fold(one, |acc, _| acc * base) } macro_rules! assert_pow { (($num:expr, $exp:expr) => $expected:expr) => {{ let result = $num.pow($exp); assert_eq!(result, $expected); - assert_eq!(result, naive_pow($num, $exp)); + assert_eq!(result, naive_pow(1, $num, $exp)); }} } assert_pow!((3u32, 0 ) => 1); diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 12a877f747820..f0fd42fc99b80 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -12,8 +12,6 @@ use io::{self, ErrorKind}; use libc; -use num::One; -use ops::Neg; #[cfg(target_os = "android")] pub use os::android as platform; #[cfg(target_os = "bitrig")] pub use os::bitrig as platform; @@ -123,9 +121,23 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { } } -pub fn cvt>(t: T) -> io::Result { - let one: T = T::one(); - if t == -one { +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} + +impl_is_minus_one! { i8 i16 i32 i64 isize } + +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) @@ -133,7 +145,8 @@ pub fn cvt>(t: T) -> io::Result { } pub fn cvt_r(mut f: F) -> io::Result - where T: One + PartialEq + Neg, F: FnMut() -> T + where T: IsMinusOne, + F: FnMut() -> T { loop { match cvt(f()) { diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 6dd4f4c3e750e..12219c1e9d42b 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -14,7 +14,6 @@ use prelude::v1::*; use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; -use num::Zero; use os::windows::ffi::{OsStrExt, OsStringExt}; use path::PathBuf; use time::Duration; @@ -178,8 +177,22 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { } } -fn cvt(i: I) -> io::Result { - if i == I::zero() { +trait IsZero { + fn is_zero(&self) -> bool; +} + +macro_rules! impl_is_zero { + ($($t:ident)*) => ($(impl IsZero for $t { + fn is_zero(&self) -> bool { + *self == 0 + } + })*) +} + +impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } + +fn cvt(i: I) -> io::Result { + if i.is_zero() { Err(io::Error::last_os_error()) } else { Ok(i) diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index b05dcf42a3324..71e164f012f1f 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -17,8 +17,6 @@ use io::{self, Read}; use libc::{c_int, c_void, c_ulong}; use mem; use net::{SocketAddr, Shutdown}; -use num::One; -use ops::Neg; use ptr; use sync::Once; use sys::c; @@ -60,11 +58,26 @@ fn last_error() -> io::Error { io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() }) } +#[doc(hidden)] +pub trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +macro_rules! impl_is_minus_one { + ($($t:ident)*) => ($(impl IsMinusOne for $t { + fn is_minus_one(&self) -> bool { + *self == -1 + } + })*) +} + +impl_is_minus_one! { i8 i16 i32 i64 isize } + /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1) /// and if so, returns the last error from the Windows socket interface. This /// function must be called before another call to the socket API is made. -pub fn cvt>(t: T) -> io::Result { - if t == -T::one() { +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { Err(last_error()) } else { Ok(t) @@ -82,7 +95,8 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { /// Just to provide the same interface as sys/unix/net.rs pub fn cvt_r(mut f: F) -> io::Result - where T: One + PartialEq + Neg, F: FnMut() -> T + where T: IsMinusOne, + F: FnMut() -> T { cvt(f()) } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index 5b0dd256b4c41..c00be91a2d74d 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -17,9 +17,8 @@ pub fn main() { // Bool => does not implement iterator. for i in false..true {} - //~^ ERROR `bool: std::num::One` is not satisfied - //~^^ ERROR `bool: std::iter::Step` is not satisfied - //~^^^ ERROR `for<'a> &'a bool: std::ops::Add` is not satisfied + //~^ ERROR `bool: std::iter::Step` is not satisfied + //~^^ ERROR `for<'a> &'a bool: std::ops::Add` is not satisfied // Unsized type. let arr: &[_] = &[1, 2, 3]; diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index 07233a43b88e2..aaf129e7b8e4a 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -117,11 +117,6 @@ pub fn main() { assert_eq!(nonsense.next(), None); assert_eq!(nonsense, RangeInclusive::Empty { at: 10 }); - // conversion - assert_eq!(0...9, (0..10).into()); - assert_eq!(0...0, (0..1).into()); - assert_eq!(RangeInclusive::Empty { at: 1 }, (1..0).into()); - // output assert_eq!(format!("{:?}", 0...10), "0...10"); assert_eq!(format!("{:?}", ...10), "...10"); diff --git a/src/tools/rustbook/main.rs b/src/tools/rustbook/main.rs index e0092f8e29e73..436dc11975336 100644 --- a/src/tools/rustbook/main.rs +++ b/src/tools/rustbook/main.rs @@ -10,7 +10,6 @@ #![deny(warnings)] -#![feature(iter_arith)] #![feature(rustc_private)] #![feature(rustdoc)] #![feature(question_mark)]