Conversation
|
r? @Darksonn rustbot has assigned @Darksonn. Use Why was this reviewer chosen?The reviewer was selected based on:
|
core/src/num/f{16,32,64,128}.rs (part 1)
| @@ -0,0 +1,326 @@ | |||
| macro_rules! float_impl { | |||
There was a problem hiding this comment.
I know it's inconsistent with how the integer macros are defined, but I think it makes more sense to use a declarative macro since there's exactly one rule. For one thing, you won't need to #[macro_use] this module and can instead just import it by name. Plus less whitespace, which is nice.
Something like:
pub macro float_impl(
Self = $SelfT:ty,
// ...
) {
/// The radix or base of the internal representation of
#[doc = concat!("`", stringify!($SelfT), "`.")]
#[$assoc_int_consts]
pub const RADIX: u32 = 2;
// ...
}Ideally all 3 would be declarative macros (or use num-traits cough), but I think this would be a good place to start? You could even split this commit into two stages:
- Replace an
impl fN { ... }with apub macro fN_impl(...) { ... }in-place. Since indentation matches the diff should be very clean. - Merge the various
fN_implmacros into the singlefloat_implmacro.
There was a problem hiding this comment.
I've switched to using a declarative macro, and split out a first commit which has the macro duplicated in all the float files so that the diff can easily be compared.
3d70e16 to
3cd9d5d
Compare
…` (part 1) The macro is duplicated in each file to allow the diff to compare changes with the previous implementation.
3cd9d5d to
6af8cac
Compare
|
@rustbot reroll |
|
I've been iffy about doing this because it comes with quite a few downsides. But one idea I thought was nice was to use macro_rules! float_method {
attr(to_bits, $fty:ty, bits_12p5 = $onebits: ) ($func:item) => {
/// Raw transmutation to u32.
/// ...
/// ```
/// assert_eq!((12.5f32).to_bits(), $bits_12p5); // bit of pseudocode, needs concat
/// ```
#[must_use = "..."]
$func
};
attr(sqrt, $fty:ty) ($func:item) => {
/// Returns the square root of a number.
///
/// Returns NaN if self is a negative number other than -0.0.
// ...
};
}
impl f32 {
#[float_method(to_bits, f32, bits_12p5 = 0x41480000)]
#[stable(feature = "float_bits_conv", since = "1.20.0")]
fn to_bits(...) { ... }
#[float_method(sqrt, f32)]
fn sqrt(...) { ... }
}
impl f64 {
#[float_method(to_bits, f64, bits_12p5 = 0x4029000000000000)]
#[stable(feature = "float_bits_conv", since = "1.20.0")]
fn to_bits(...) { ... }
#[float_method(sqrt, f64)]
fn sqrt(...) { ... }
}That way we can reuse the docs but the code stays much more readable. E.g. the rustdoc "source" links still point to the right place, we don't need to mess with attributes quite as much, and it's fine when an implementation occasionally needs to deviate. |
Now there are 4 primitive floating point types, the code for each method/constant is duplicated 4 times, once on each type. This PR begins reducing the duplication by moving the code in
impl f{16,32,64,128}incoreinto afloat_impl!macro, similar to the existingint_impl!anduint_impl!macros (which are used for 6 primitive types each). To reduce merge conflicts and make this easier to review, I'm going to move the items in chunks: this PR just moves the associated constants.The PR is split into two commits, with the first commit having the macro duplicated in all 4 individual float files so that the diff can compare the macro with the original implementation.