-
Notifications
You must be signed in to change notification settings - Fork 149
traits: Introduce std feature #296
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
Conversation
This makes it possible to build `traits` without `std`. For this a new trait `BasicFloat` was introduced, implementing some basic functionality that works with `core`. Most notably this is lacking functions like `cos`, `sin`, etc. `Float` is not available without `std`. Refs rust-num#216.
There's a CI failure reported across all versions. I think this probably needs some direct no-std testing in Did you consider just gating If you really want to have two separate traits, maybe it would be better to have |
Hmm, but that's a breaking change for implementors. :/ |
Yes, I considered that, but discarded it for this reason. I like your suggestion of gating the methods, this would have the advantage that there will be no redundant reimplementation of the methods currently in |
Set up AppVeyor
This removes the `BasicFloat` trait.
I did what you suggested, which coincidentally also fixed the tests. I added quite a few default implementations to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a few tweaks requested.
We should probably also add a caution in the docs for implementors of Float
. Those that implement it normally are fine, but if someone now chooses to implement Float
only for no_std
, their build will fail if anyone else in the entire dependency graph enables num-traits/std
.
ci/test_full.sh
Outdated
@@ -10,6 +10,10 @@ for package in bigint complex integer iter rational traits; do | |||
cargo test --manifest-path $package/Cargo.toml | |||
done | |||
|
|||
# Only num-tratis supports no_std at the moment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sp "tratis"
traits/src/float.rs
Outdated
} | ||
} | ||
acc | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use the generic num_traits::pow()
once exp
is positive? I see your implementation is identical, but we don't need to duplicate code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that num_traits::pow
takes a usize
for the exponent, which might be smaller than i32
in the future. That is why I duplicated the implementation.
If we made a breaking change, then we could consolidate the two implementations by making num_traits::pow
use a u32
for the exponent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, do 16-bit targets even have these floats? But OK, not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. I could use num_traits::pow
and cast, hoping it works. Alternatively we could use a macro to deduplicate the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or instead of casting, use FromPrimitive
and unwrap
.
/// assert!(abs_difference < 1e-10); | ||
/// ``` | ||
#[cfg(not(feature = "std"))] | ||
fn to_degrees(self) -> Self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, that's annoying to have a separate declaration, but I don't see a better way, other than excluding it from no_std
entirely.
traits/src/float.rs
Outdated
@@ -1097,117 +1287,138 @@ macro_rules! float_impl { | |||
fn to_degrees(self) -> Self { | |||
// NB: `f32` didn't stabilize this until 1.7 | |||
// <$T>::to_degrees(self) | |||
self * (180. / ::std::$T::consts::PI) | |||
self * (180. / ::core::$T::consts::PI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our baseline is now 1.8 - can we just use the native implementation?
traits/src/float.rs
Outdated
} | ||
|
||
#[inline] | ||
fn to_radians(self) -> Self { | ||
// NB: `f32` didn't stabilize this until 1.7 | ||
// <$T>::to_radians(self) | ||
self * (::std::$T::consts::PI / 180.) | ||
self * (::core::$T::consts::PI / 180.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto on using the native impl.
@cuviper I think I addressed all your comments. |
// NB: `f32` didn't stabilize this until 1.7 | ||
// <$T>::to_degrees(self) | ||
self * (180. / ::std::$T::consts::PI) | ||
<$T>::to_degrees(self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this doesn't work for no_std, because the inherent methods are in std. So it recurses:
warning: function cannot return without recurring
--> src\float.rs:1272:13
|
1272 | fn to_degrees(self) -> Self {
| _____________^ starting here...
1273 | | <$T>::to_degrees(self)
1274 | | }
| |_____________^ ...ending here
...
1482 | float_impl!(f32 integer_decode_f32 classify_f32);
| ------------------------------------------------- in this macro invocation
|
= note: #[warn(unconditional_recursion)] on by default
I guess we have to roll our own, but it's not a big deal since these are trivial.
Can you add #![deny(unconditional_recursion)]
to the crate? This seems like a problem we're vulnerable to in general, with so many traits that are supposed to forward calls...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I actually wanted to keep the implementation for no_std
but forgot about it...
Should be fixed in the most recent commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks!
@homu r+ |
📌 Commit ba73ba2 has been approved by |
traits: Introduce std feature This makes it possible to build `traits` without `std`. For this a new trait `BasicFloat` was introduced, implementing some basic functionality that works with `core`. Most notably this is lacking functions like `cos`, `sin`, etc. `Float` is not available without `std`. Refs #216.
☀️ Test successful - status |
This is a breaking change and the release should be yanked. Feature-gating things that were previously not feature-gated is a breaking change. |
This is a port of @vks's rust-num/num#296, but without the feature- toggled changes to `Float`.
30: Re-introduce the std feature r=vks a=cuviper This is a port of @vks's rust-num/num#296, but without the feature-toggled changes to `Float`. Now `Float` and the newer `Real` are completely dependent on having `std` enabled. In the future we can consider adding separate more-limited float/real traits that can work without `std`, like the `BaseFloat` that was originally proposed in the former PR. This is a breaking change with a bump to 0.2, since anyone currently using `default-features = false` will lose functionality. The actual API is otherwise unchanged, so my plan is to employ the "semver trick" -- publishing a new num-traits-0.1 that re-exports everything from 0.2 (with `std`). Thus all `num-traits` users should remain compatible even if they mix 0.1 and 0.2. Closes #16.
This makes it possible to build
traits
withoutstd
. For this a newtrait
BasicFloat
was introduced, implementing some basic functionalitythat works with
core
. Most notably this is lacking functions likecos
,sin
, etc.Float
is not available withoutstd
.Refs #216.