diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-06-28 08:56:56 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-07-03 10:49:01 -0700 |
| commit | 3016626c3aa4bc44807e54a8ba8b9e367ff566f5 (patch) | |
| tree | 4dd6d30026ff2b9af406e1923e9f954da8e62690 | |
| parent | 375fa6ef371a0ae248968d363226101ef741127e (diff) | |
| download | rust-3016626c3aa4bc44807e54a8ba8b9e367ff566f5.tar.gz rust-3016626c3aa4bc44807e54a8ba8b9e367ff566f5.zip | |
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)
36 files changed, 507 insertions, 194 deletions
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 140801737bc..b9f5c6fcab9 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -825,8 +825,6 @@ impl<T: Ord> BinaryHeap<T> { /// Basic usage: /// /// ``` - /// #![feature(binary_heap_append)] - /// /// use std::collections::BinaryHeap; /// /// let v = vec![-10, 1, 2, 3, 3]; @@ -840,9 +838,7 @@ impl<T: Ord> BinaryHeap<T> { /// 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 3b775dc2865..aea7a1c13a2 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -559,7 +559,6 @@ impl<K: Ord, V> BTreeMap<K, V> { /// # Examples /// /// ``` - /// #![feature(btree_append)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -583,8 +582,7 @@ impl<K: Ord, V> BTreeMap<K, V> { /// 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<K: Ord, V> BTreeMap<K, V> { /// Basic usage: /// /// ``` - /// #![feature(btree_split_off)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -936,9 +933,7 @@ impl<K: Ord, V> BTreeMap<K, V> { /// 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<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where K: Borrow<Q> { diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index c47eb0b3fad..0f885bc2950 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -551,7 +551,6 @@ impl<T: Ord> BTreeSet<T> { /// # Examples /// /// ``` - /// #![feature(btree_append)] /// use std::collections::BTreeSet; /// /// let mut a = BTreeSet::new(); @@ -575,8 +574,7 @@ impl<T: Ord> BTreeSet<T> { /// 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<T: Ord> BTreeSet<T> { /// Basic usage: /// /// ``` - /// #![feature(btree_split_off)] /// use std::collections::BTreeMap; /// /// let mut a = BTreeMap::new(); @@ -611,9 +608,7 @@ impl<T: Ord> BTreeSet<T> { /// 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<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where T: Borrow<Q> { BTreeSet { map: self.map.split_off(key) } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7ac01103d61..f027d074cb6 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 6161bad7468..8ae63808f27 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 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 diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 88d73df937f..c6bceab7931 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 4c0a403e574..1a3533317da 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::<f64>(Fp { f: sig, e: 0 }).integer_decode(); + let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 })); assert_eq!(e1, 0 + 64 - 53); - let (m2, e2, _) = fp_to_float::<f64>(Fp { f: sig, e: 55 }).integer_decode(); + let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 })); assert_eq!(e2, 55 + 64 - 53); assert_eq!(m2, m1); - let (m3, e3, _) = fp_to_float::<f64>(Fp { f: sig, e: -78 }).integer_decode(); + let (m3, e3, _) = integer_decode(fp_to_float::<f64>(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::<f64>(fp), x); } diff --git a/src/libcoretest/num/flt2dec/estimator.rs b/src/libcoretest/num/flt2dec/estimator.rs index 21260c520f6..857aae72c8a 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 1a592f3ad42..0f4d19e7092 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<F, T>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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<F>(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 eb9dd7dfcb3..48ea953cc1e 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 2da9a55f1fd..726ba4fc192 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 c369858556d..9cb5d8b6ad6 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 7ccff7ad3d8..6239506c2d7 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 17d412411c0..7a676c041ad 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 70b7706535c..67a1c302483 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 d33df05acf2..20804d62dfa 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<T>(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<T: Mul<Output=T> + One + Copy>(base: T, exp: usize) -> T { - let one: T = T::one(); + fn naive_pow<T: Mul<Output=T> + 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 12a877f7478..f0fd42fc99b 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: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> { - 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: IsMinusOne>(t: T) -> io::Result<T> { + if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) @@ -133,7 +145,8 @@ pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> { } pub fn cvt_r<T, F>(mut f: F) -> io::Result<T> - where T: One + PartialEq + Neg<Output=T>, 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 6dd4f4c3e75..12219c1e9d4 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: PartialEq + Zero>(i: I) -> io::Result<I> { - 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: IsZero>(i: I) -> io::Result<I> { + 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 b05dcf42a33..71e164f012f 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: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> { - if t == -T::one() { +pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> { + 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<T, F>(mut f: F) -> io::Result<T> - where T: One + PartialEq + Neg<Output=T>, 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 5b0dd256b4c..c00be91a2d7 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 07233a43b88..aaf129e7b8e 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 e0092f8e29e..436dc119753 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)] |
