From 8d7f2e455a1125ab148cf0a46ca164d813131153 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 21 May 2015 09:02:04 -0400 Subject: [PATCH] Use associated constants in `std::num::{Zero,One}` This commit causes an ICE! --- src/libcore/fmt/num.rs | 2 +- src/libcore/iter.rs | 16 ++++++------ src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 44 ++++++++++++++------------------- src/libstd/num/mod.rs | 2 +- src/libstd/sys/unix/mod.rs | 2 +- src/libstd/sys/windows/mod.rs | 2 +- src/libstd/sys/windows/net.rs | 2 +- src/test/run-pass/issue-8460.rs | 20 +++++++-------- 9 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 122fffc595905..1168cb1b70972 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -52,7 +52,7 @@ trait GenericRadix { fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { // The radix can be as low as 2, so we need a buffer of at least 64 // characters for a base 2 number. - let zero = T::zero(); + let zero = T::ZERO; let is_positive = x >= zero; let mut buf = [0; 64]; let mut curr = buf.len(); diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 74f3eccab6830..a358a54f8f03c 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1075,7 +1075,7 @@ pub trait Iterator { S: Add + Zero, Self: Sized, { - self.fold(Zero::zero(), |s, e| s + e) + self.fold(Zero::ZERO, |s, e| s + e) } /// Iterates over the entire iterator, multiplying all the elements @@ -1097,7 +1097,7 @@ pub trait Iterator { P: Mul + One, Self: Sized, { - self.fold(One::one(), |p, e| p * e) + self.fold(One::ONE, |p, e| p * e) } } @@ -2840,7 +2840,7 @@ impl DoubleEndedIterator for RangeInclusive where fn next_back(&mut self) -> Option { if self.range.end > self.range.start { let result = self.range.end.clone(); - self.range.end = &self.range.end - &A::one(); + self.range.end = &self.range.end - &A::ONE; Some(result) } else if !self.done && self.range.start == self.range.end { self.done = true; @@ -2858,7 +2858,7 @@ impl Iterator for StepBy> { #[inline] fn next(&mut self) -> Option { - let rev = self.step_by < A::zero(); + let rev = self.step_by < A::ZERO; if (rev && self.range.start > self.range.end) || (!rev && self.range.start < self.range.end) { @@ -2906,7 +2906,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 + &A::ONE; mem::swap(&mut n, &mut self.start); Some(n) } else { @@ -2916,7 +2916,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(&self.start, &self.end, &A::ONE) { Some(hint) => (hint, Some(hint)), None => (0, None) } @@ -2936,7 +2936,7 @@ impl DoubleEndedIterator for ops::Range where #[inline] fn next_back(&mut self) -> Option { if self.start < self.end { - self.end = &self.end - &A::one(); + self.end = &self.end - &A::ONE; Some(self.end.clone()) } else { None @@ -2953,7 +2953,7 @@ impl Iterator for ops::RangeFrom where #[inline] fn next(&mut self) -> Option { - let mut n = &self.start + &A::one(); + let mut n = &self.start + &A::ONE; mem::swap(&mut n, &mut self.start); Some(n) } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 0794fb0c45dee..0c7880a7b2eb5 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -67,6 +67,7 @@ #![feature(on_unimplemented)] #![feature(simd)] #![feature(staged_api)] +#![feature(associated_consts)] #![feature(unboxed_closures)] #![feature(rustc_attrs)] #![feature(optin_builtin_traits)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index bf26022692d09..66a74794cab32 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -50,34 +50,30 @@ pub mod flt2dec; /// Types that have a "zero" value. /// /// This trait is intended for use in conjunction with `Add`, as an identity: -/// `x + T::zero() == x`. -#[unstable(feature = "zero_one", - reason = "unsure of placement, wants to use associated constants")] +/// `x + T::ZERO == x`. +#[unstable(feature = "zero_one", reason = "unsure of placement")] pub trait Zero { /// The "zero" (usually, additive identity) for this type. - fn zero() -> Self; + const ZERO: Self; } /// Types that have a "one" value. /// /// This trait is intended for use in conjunction with `Mul`, as an identity: -/// `x * T::one() == x`. -#[unstable(feature = "zero_one", - reason = "unsure of placement, wants to use associated constants")] +/// `x * T::ONE == x`. +#[unstable(feature = "zero_one", reason = "unsure of placement")] pub trait One { /// The "one" (usually, multiplicative identity) for this type. - fn one() -> Self; + const ONE: Self; } macro_rules! zero_one_impl { ($($t:ty)*) => ($( impl Zero for $t { - #[inline] - fn zero() -> Self { 0 } + const ZERO: $t = 0; } impl One for $t { - #[inline] - fn one() -> Self { 1 } + const ONE: $t = 1; } )*) } @@ -86,12 +82,10 @@ zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } macro_rules! zero_one_impl_float { ($($t:ty)*) => ($( impl Zero for $t { - #[inline] - fn zero() -> Self { 0.0 } + const ZERO: $t = 0.0; } impl One for $t { - #[inline] - fn one() -> Self { 1.0 } + const ONE: $t = 1.0; } )*) } @@ -415,7 +409,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 >= Self::ZERO => Self::max_value(), None => Self::min_value(), } } @@ -427,7 +421,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 >= Self::ZERO => Self::min_value(), None => Self::max_value(), } } @@ -535,7 +529,7 @@ macro_rules! int_impl { #[inline] pub fn pow(self, mut exp: u32) -> Self { let mut base = self; - let mut acc = Self::one(); + let mut acc = Self::ONE; let mut prev_base = self; let mut base_oflo = false; @@ -985,7 +979,7 @@ macro_rules! uint_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 >= Self::ZERO => Self::max_value(), None => Self::min_value(), } } @@ -997,7 +991,7 @@ macro_rules! uint_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 >= Self::ZERO => Self::min_value(), None => Self::max_value(), } } @@ -1103,7 +1097,7 @@ macro_rules! uint_impl { #[inline] pub fn pow(self, mut exp: u32) -> Self { let mut base = self; - let mut acc = Self::one(); + let mut acc = Self::ONE; let mut prev_base = self; let mut base_oflo = false; @@ -1131,8 +1125,8 @@ 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(Self::ONE)) & self == Self::ZERO && + !(self == Self::ZERO) } /// Returns the smallest power of two greater than or equal to `self`. @@ -1141,7 +1135,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::ONE; one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits) } diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 9a52a0214e9cc..29a937b830459 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -202,7 +202,7 @@ mod tests { #[test] fn test_pow() { fn naive_pow + One + Copy>(base: T, exp: usize) -> T { - let one: T = T::one(); + let one: T = T::ONE; (0..exp).fold(one, |acc, _| acc * base) } macro_rules! assert_pow { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index c1a4e8cee9ed4..d3ae9194a0885 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -75,7 +75,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { } pub fn cvt>(t: T) -> io::Result { - let one: T = T::one(); + let one: T = T::ONE; if t == -one { Err(io::Error::last_os_error()) } else { diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 6b7bff2c1c6f8..ad936eede3da8 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -145,7 +145,7 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { } fn cvt(i: I) -> io::Result { - if i == I::zero() { + if i == I::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 6bbcd968157ab..380daa48f2421 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -50,7 +50,7 @@ fn last_error() -> io::Error { /// 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 + PartialEq>(t: T) -> io::Result { - let one: T = T::one(); + let one: T = T::ONE; if t == -one { Err(last_error()) } else { diff --git a/src/test/run-pass/issue-8460.rs b/src/test/run-pass/issue-8460.rs index 4ebc43163ede8..f6d178ca6c698 100644 --- a/src/test/run-pass/issue-8460.rs +++ b/src/test/run-pass/issue-8460.rs @@ -19,19 +19,19 @@ fn main() { assert!(thread::spawn(move|| { i16::min_value() / -1; }).join().is_err()); assert!(thread::spawn(move|| { i32::min_value() / -1; }).join().is_err()); assert!(thread::spawn(move|| { i64::min_value() / -1; }).join().is_err()); - assert!(thread::spawn(move|| { 1isize / isize::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i8 / i8::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i16 / i16::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i32 / i32::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i64 / i64::zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1isize / isize::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i8 / i8::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i16 / i16::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i32 / i32::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i64 / i64::ZERO; }).join().is_err()); assert!(thread::spawn(move|| { isize::min_value() % -1; }).join().is_err()); assert!(thread::spawn(move|| { i8::min_value() % -1; }).join().is_err()); assert!(thread::spawn(move|| { i16::min_value() % -1; }).join().is_err()); assert!(thread::spawn(move|| { i32::min_value() % -1; }).join().is_err()); assert!(thread::spawn(move|| { i64::min_value() % -1; }).join().is_err()); - assert!(thread::spawn(move|| { 1isize % isize::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i8 % i8::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i16 % i16::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i32 % i32::zero(); }).join().is_err()); - assert!(thread::spawn(move|| { 1i64 % i64::zero(); }).join().is_err()); + assert!(thread::spawn(move|| { 1isize % isize::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i8 % i8::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i16 % i16::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i32 % i32::ZERO; }).join().is_err()); + assert!(thread::spawn(move|| { 1i64 % i64::ZERO; }).join().is_err()); }