From 152c76ef0d62b2529b50356773ac6907a6db0f6e Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Mon, 24 Aug 2015 17:47:01 +0200 Subject: [PATCH 1/2] Minimize the implementation of `Rem` in libcore The implementation of the remainder operation belongs to librustc_trans, but it is also stubbed out in libcore in order to expose it as a trait on primitive types. Instead of exposing some implementation details (like the upcast to `f64` in MSVC), use a minimal implementation just like that of the `Div` trait. --- src/libcore/ops.rs | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 7c386c6c33e43..ecf80d7e30ae2 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -423,7 +423,7 @@ pub trait Rem { fn rem(self, rhs: RHS) -> Self::Output; } -macro_rules! rem_impl { +macro_rules! rem_impl_integer { ($($t:ty)*) => ($( /// This operation satisfies `n % d == n - (n / d) * d`. The /// result has the same sign as the left operand. @@ -439,42 +439,23 @@ macro_rules! rem_impl { )*) } -rem_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } -#[stable(feature = "rust1", since = "1.0.0")] -impl Rem for f32 { - type Output = f32; - - // The builtin f32 rem operator is broken when targeting - // MSVC; see comment in std::f32::floor. - // FIXME: See also #27859. - #[inline] - #[cfg(target_env = "msvc")] - fn rem(self, other: f32) -> f32 { - (self as f64).rem(other as f64) as f32 - } - - #[inline] - #[cfg(not(target_env = "msvc"))] - fn rem(self, other: f32) -> f32 { - extern { fn fmodf(a: f32, b: f32) -> f32; } - unsafe { fmodf(self, other) } - } -} +macro_rules! rem_impl_float { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Rem for $t { + type Output = $t; -#[stable(feature = "rust1", since = "1.0.0")] -impl Rem for f64 { - type Output = f64; + #[inline] + fn rem(self, other: $t) -> $t { self % other } + } - #[inline] - fn rem(self, other: f64) -> f64 { - extern { fn fmod(a: f64, b: f64) -> f64; } - unsafe { fmod(self, other) } - } + forward_ref_binop! { impl Rem, rem for $t, $t } + )*) } -forward_ref_binop! { impl Rem, rem for f64, f64 } -forward_ref_binop! { impl Rem, rem for f32, f32 } +rem_impl_float! { f32 f64 } /// The `Neg` trait is used to specify the functionality of unary `-`. /// From 4653a8b3fd69dbab366a8ec67ae9cf68dc128c43 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Thu, 27 Aug 2015 10:06:54 +0200 Subject: [PATCH 2/2] Restore removed code and mark it for usage in stage0 The old code is temporarily needed in order to keep the MSVC build working. It should be possible to remove this code after the bootstrap compiler is updated to contain the MSVC workaround from #27875. --- src/libcore/ops.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index ecf80d7e30ae2..3fb720ab6c83c 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -441,6 +441,7 @@ macro_rules! rem_impl_integer { rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg(not(stage0))] macro_rules! rem_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] @@ -455,8 +456,48 @@ macro_rules! rem_impl_float { )*) } +#[cfg(not(stage0))] rem_impl_float! { f32 f64 } +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] +impl Rem for f32 { + type Output = f32; + + // The builtin f32 rem operator is broken when targeting + // MSVC; see comment in std::f32::floor. + // FIXME: See also #27859. + #[inline] + #[cfg(target_env = "msvc")] + fn rem(self, other: f32) -> f32 { + (self as f64).rem(other as f64) as f32 + } + + #[inline] + #[cfg(not(target_env = "msvc"))] + fn rem(self, other: f32) -> f32 { + extern { fn fmodf(a: f32, b: f32) -> f32; } + unsafe { fmodf(self, other) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] +impl Rem for f64 { + type Output = f64; + + #[inline] + fn rem(self, other: f64) -> f64 { + extern { fn fmod(a: f64, b: f64) -> f64; } + unsafe { fmod(self, other) } + } +} + +#[cfg(stage0)] +forward_ref_binop! { impl Rem, rem for f64, f64 } +#[cfg(stage0)] +forward_ref_binop! { impl Rem, rem for f32, f32 } + /// The `Neg` trait is used to specify the functionality of unary `-`. /// /// # Examples