-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Floating point modulus has snuck back into the language #27824
Comments
Also cc #27823 where this was discovered |
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. :( |
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. |
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. |
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 |
Isn't it possible to do the same as in #27823, i.e. move the definition of the modulus operator to std? |
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. |
Ah yeah I'm fine with libcore having a dependency on |
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 |
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. |
Would it be possible to remove the double implementation in libcore and trans and only keep a single one? |
Back in 1563ea9 we decided to remove the
%
operator from floats in the language, relegating the implementations of theRem
trait to library calls on thefmod
andfmodf
functions. (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
The text was updated successfully, but these errors were encountered: