Skip to content

Commit

Permalink
Use associated constants in std::num::{Zero,One}
Browse files Browse the repository at this point in the history
This commit causes an ICE!
  • Loading branch information
tamird committed May 26, 2015
1 parent 0ea80fa commit 8d7f2e4
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 48 deletions.
2 changes: 1 addition & 1 deletion src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ trait GenericRadix {
fn fmt_int<T: 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();
Expand Down
16 changes: 8 additions & 8 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ pub trait Iterator {
S: Add<Self::Item, Output=S> + 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
Expand All @@ -1097,7 +1097,7 @@ pub trait Iterator {
P: Mul<Self::Item, Output=P> + One,
Self: Sized,
{
self.fold(One::one(), |p, e| p * e)
self.fold(One::ONE, |p, e| p * e)
}
}

Expand Down Expand Up @@ -2840,7 +2840,7 @@ impl<A> DoubleEndedIterator for RangeInclusive<A> where
fn next_back(&mut self) -> Option<A> {
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;
Expand All @@ -2858,7 +2858,7 @@ impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {

#[inline]
fn next(&mut self) -> Option<A> {
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)
{
Expand Down Expand Up @@ -2906,7 +2906,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 + &A::ONE;
mem::swap(&mut n, &mut self.start);
Some(n)
} else {
Expand All @@ -2916,7 +2916,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(&self.start, &self.end, &A::ONE) {
Some(hint) => (hint, Some(hint)),
None => (0, None)
}
Expand All @@ -2936,7 +2936,7 @@ impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
#[inline]
fn next_back(&mut self) -> Option<A> {
if self.start < self.end {
self.end = &self.end - &A::one();
self.end = &self.end - &A::ONE;
Some(self.end.clone())
} else {
None
Expand All @@ -2953,7 +2953,7 @@ impl<A: Step + One> Iterator for ops::RangeFrom<A> where

#[inline]
fn next(&mut self) -> Option<A> {
let mut n = &self.start + &A::one();
let mut n = &self.start + &A::ONE;
mem::swap(&mut n, &mut self.start);
Some(n)
}
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
44 changes: 19 additions & 25 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
)*)
}
Expand All @@ -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;
}
)*)
}
Expand Down Expand Up @@ -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(),
}
}
Expand All @@ -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(),
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
}
}
Expand All @@ -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(),
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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`.
Expand All @@ -1141,7 +1135,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::ONE;
one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
}

Expand Down
2 changes: 1 addition & 1 deletion src/libstd/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ 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();
let one: T = T::ONE;
(0..exp).fold(one, |acc, _| acc * base)
}
macro_rules! assert_pow {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ 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();
let one: T = T::ONE;
if t == -one {
Err(io::Error::last_os_error())
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ 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() {
if i == I::ZERO {
Err(io::Error::last_os_error())
} else {
Ok(i)
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/windows/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: One + Neg<Output=T> + PartialEq>(t: T) -> io::Result<T> {
let one: T = T::one();
let one: T = T::ONE;
if t == -one {
Err(last_error())
} else {
Expand Down
20 changes: 10 additions & 10 deletions src/test/run-pass/issue-8460.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

0 comments on commit 8d7f2e4

Please sign in to comment.