Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upFloating point modulus has snuck back into the language #27824
Comments
alexcrichton
added
I-nominated
T-lang
labels
Aug 13, 2015
This comment has been minimized.
This comment has been minimized.
|
Also cc #27823 where this was discovered |
This comment has been minimized.
This comment has been minimized.
|
I don't think it's in the language: #![crate_type = "lib"]
#![feature(lang_items, no_core)]
#![no_core]
fn foo() {
1_f32 % 2_f32;
}
#[lang = "sized"] trait Sized {}Fails to compile:
In fact, there are explicit implementations of #[stable(feature = "rust1", since = "1.0.0")]
impl Rem for f32 {
type Output = f32;
// see notes in `core::f32::Float::floor`
#[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")]
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) }
}
}I suspect this can't be removed backwards compatibly. :( |
This comment has been minimized.
This comment has been minimized.
|
Actually, the situation is kind of confusing: "%" doesn't typecheck unless there's an explicit implementation of Rem visible. However, trans assumes that "impl Rem for f64" is implemented the obvious way, and generates code which doesn't actually use the explicit implementation. |
This comment has been minimized.
This comment has been minimized.
|
Yeah I don't think that this is that serious of a decision to make either way really, just figured we may want to make a decision one way or the other to be definitive. Either way the surface language is the same and the implementation will be the same, it's just a manner of implementation details. |
This comment has been minimized.
This comment has been minimized.
|
Actually my initial assessment wasn't quite right, it would be a strictly-speaking backwards-incompatible change to do remove this from the language again. Right now we allow |
huonw
referenced this issue
Aug 18, 2015
Merged
trans: Call `fmod` manually for 32-bit float rem #27875
This comment has been minimized.
This comment has been minimized.
|
Isn't it possible to do the same as in #27823, i.e. move the definition of the modulus operator to std? |
This comment has been minimized.
This comment has been minimized.
|
So -- the reason this changed behavior is because I forgot about this case. I think we could restore the old behavior by modifying UPDATE -- what the compiler does now is use the impls during typechecking, but then if the impl is between two scalar types, fallback to builtin semantics. |
This comment has been minimized.
This comment has been minimized.
|
Ah yeah I'm fine with libcore having a dependency on |
This comment has been minimized.
This comment has been minimized.
|
We discussed this in the language subteam meeting. The general conclusion was that the current behavior is OK, and in particular that the older behavior (in an impl but not "the language") was not especially coherent or interesting. In particular, the motivating problem seems to be that LLVM inserts a call to |
nikomatsakis
removed
the
I-nominated
label
Aug 24, 2015
This comment has been minimized.
This comment has been minimized.
|
I'm removing the nominating tag and closing this issue, but please feel free to re-open if you think the summary and conclusions from #27824 (comment) are not sufficient. |
nikomatsakis
closed this
Aug 24, 2015
This comment has been minimized.
This comment has been minimized.
|
Would it be possible to remove the double implementation in libcore and trans and only keep a single one? |
alexcrichton commentedAug 13, 2015
Back in 1563ea9 we decided to remove the
%operator from floats in the language, relegating the implementations of theRemtrait to library calls on thefmodandfmodffunctions. (some discussion in #12278)One of the reasons cited for its removal was the removal of support from LLVM, although I don't think that's happened yet and I'm not quite sure what the status there is.
Regardless, we can probably still remove this without affecting backwards compatibility, but we'd probably want to do so sooner rather than later. Would just be good to make sure we've got our ducks in a row!
Nominating