Skip to content

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

Merged
merged 9 commits into from
Jun 9, 2017
Merged

traits: Introduce std feature #296

merged 9 commits into from
Jun 9, 2017

Conversation

vks
Copy link
Contributor

@vks vks commented May 31, 2017

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.

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.
@cuviper
Copy link
Member

cuviper commented May 31, 2017

There's a CI failure reported across all versions. I think this probably needs some direct no-std testing in ci/test_full.sh too.

Did you consider just gating #[cfg(feature = "std")] on Float methods as needed? I know that makes a lot more places that have to be marked, but I think it's easier to explain. I don't like the method duplication, and I don't want users to be confused about when to use Float or BasicFloat.

If you really want to have two separate traits, maybe it would be better to have Float: BasicFloat so they are directly related.

@cuviper
Copy link
Member

cuviper commented May 31, 2017

maybe it would be better to have Float: BasicFloat

Hmm, but that's a breaking change for implementors. :/

@vks
Copy link
Contributor Author

vks commented May 31, 2017

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 BasicFloat if std is available.

remexre pushed a commit to remexre/num that referenced this pull request Jun 1, 2017
@vks
Copy link
Contributor Author

vks commented Jun 2, 2017

I did what you suggested, which coincidentally also fixed the tests.

I added quite a few default implementations to Float. They only matter for no_std at the moment.

Copy link
Member

@cuviper cuviper left a 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sp "tratis"

}
}
acc
}
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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;
Copy link
Member

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.

@@ -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)
Copy link
Member

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?

}

#[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.)
Copy link
Member

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.

@vks
Copy link
Contributor Author

vks commented Jun 7, 2017

@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)
Copy link
Member

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...

Copy link
Contributor Author

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.

Copy link
Member

@cuviper cuviper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks!

@cuviper
Copy link
Member

cuviper commented Jun 9, 2017

@homu r+

@homu
Copy link
Contributor

homu commented Jun 9, 2017

📌 Commit ba73ba2 has been approved by cuviper

homu added a commit that referenced this pull request Jun 9, 2017
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.
@homu
Copy link
Contributor

homu commented Jun 9, 2017

⌛ Testing commit ba73ba2 with merge 8b5d4ac...

@homu
Copy link
Contributor

homu commented Jun 9, 2017

☀️ Test successful - status

@homu homu merged commit ba73ba2 into rust-num:master Jun 9, 2017
@nox
Copy link

nox commented Jun 9, 2017

This is a breaking change and the release should be yanked. Feature-gating things that were previously not feature-gated is a breaking change.

cuviper added a commit to cuviper/num that referenced this pull request Jun 9, 2017
This reverts commit 8b5d4ac, reversing
changes made to ef752e4.
homu added a commit that referenced this pull request Jun 9, 2017
Revert "Auto merge of #296 - vks:no_std, r=cuviper"

This reverts commit 8b5d4ac, reversing
changes made to ef752e4.

See #297 -- it's a breaking change to feature-gate existing APIs.
cuviper pushed a commit to cuviper/num-traits that referenced this pull request Feb 1, 2018
This is a port of @vks's rust-num/num#296, but without the feature-
toggled changes to `Float`.
bors bot added a commit to rust-num/num-traits that referenced this pull request Feb 2, 2018
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants