-
Notifications
You must be signed in to change notification settings - Fork 432
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
Add TryRngCore
and TryCryptoRng
traits
#1424
Conversation
UPD: This no longer relevant, blanket impls are reversed now. |
/// ``` | ||
/// | ||
/// [getrandom]: https://crates.io/crates/getrandom | ||
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))] | ||
#[derive(Clone, Copy, Debug, Default)] | ||
pub struct OsRng; | ||
|
||
impl CryptoRng for OsRng {} | ||
impl TryRngCore for OsRng { | ||
type Error = getrandom::Error; |
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.
This exposes getrandom::Error
as part of rand_core
's public API (same with SeedableRng::try_from_entropy
). I think it's fine since getrandom
is quite stable and we no longer need error boxing provided by rand_core::Error
.
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.
A caveat is that we can't release rand_core
v1.0 before getrandom
v1.0, but maybe we shouldn't care about that.
I think otherwise this is perfectly fine.
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.
It will also prevent rand 0.9
from updating its version of getrandom
to getrandom 1.0
without a breaking change. We could also just note that the exact type of OsRng::Error
isn't considered part of rand
's stable API.
All that considered, this seems fine. It's much better to directly expose getrandom::Error
than do the wrapping we were doing before.
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.
In some cases the semver trick could allow such migration without breaking changes.
Since this includes a bunch of reformatting, would it be easy enough to make a new PR applying rustfmt then rebase this? The only reason I didn't do that yet is because of conflicts with other PRs. |
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.
I like this, though given that it's a very significant change, we shouldn't rush this.
We might also reconsider #1288 afterwards, though I'm pretty sure the renames in that will cause more conflicts than these changes.
rand_core/src/lib.rs
Outdated
pub use error::Error; | ||
#[cfg(feature = "getrandom")] pub use os::OsRng; | ||
|
||
use core::{convert::Infallible, fmt}; | ||
|
||
pub mod block; | ||
mod error; | ||
pub mod impls; | ||
pub mod le; | ||
#[cfg(feature = "getrandom")] mod os; | ||
|
||
#[cfg(feature = "getrandom")] pub use getrandom; | ||
#[cfg(feature = "getrandom")] pub use os::OsRng; |
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.
I suspect most people (including myself) will be happy to see rand_core::Error
gone, but I wonder if it will cause problems (for an alloc
-less no_std
crate which needs to handle errors).
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.
I don't think it should cause any issues. getrandom::Error
is a no_std
type by default. Defining an IO RNG which uses something like io::Error
would make it automatically incompatible with no_std
. So everything will depend on implementer crates.
/// ``` | ||
/// | ||
/// [getrandom]: https://crates.io/crates/getrandom | ||
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))] | ||
#[derive(Clone, Copy, Debug, Default)] | ||
pub struct OsRng; | ||
|
||
impl CryptoRng for OsRng {} | ||
impl TryRngCore for OsRng { | ||
type Error = getrandom::Error; |
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.
A caveat is that we can't release rand_core
v1.0 before getrandom
v1.0, but maybe we shouldn't care about that.
I think otherwise this is perfectly fine.
Also note: there are some doc link errors to fix. |
This is a cool change, I think the new design is quite elegant! |
One open question is whether we need to distinguish between Having only |
For expressiveness and symmetry I would say keep it. But if it is having a significant impact on ergonomics then maybe there's a better design to be strived for? |
An example of a fallible non-crypto RNG could be reading from a file, but we already removed I don't see much use for |
The only case I could think of is RDRAND/RDSEED instructions which produce |
@josephlr it would be nice to get your thoughts on the usage of |
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 reasonable to me. Having two maker traits for being cryptographically secure is a little weird, but the alternative would be having a marker trait with no methods, and the requiring all users to do T: TryRngCore + CryptoRng
which seems worse.
It's also unfortunate that the blanket impl for TryRngCore
in terms of RngCore
is not currently compatible with Rust's trait system, but I guess that can't be avoided.
/// ``` | ||
/// | ||
/// [getrandom]: https://crates.io/crates/getrandom | ||
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))] | ||
#[derive(Clone, Copy, Debug, Default)] | ||
pub struct OsRng; | ||
|
||
impl CryptoRng for OsRng {} | ||
impl TryRngCore for OsRng { | ||
type Error = getrandom::Error; |
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.
It will also prevent rand 0.9
from updating its version of getrandom
to getrandom 1.0
without a breaking change. We could also just note that the exact type of OsRng::Error
isn't considered part of rand
's stable API.
All that considered, this seems fine. It's much better to directly expose getrandom::Error
than do the wrapping we were doing before.
It could be avoided, but we would need to give up on the blanket impls for |
Also to a hypothetical We should not rely on documentation for API stability (at least, only as a very last resort). There are always people who don't read it.
I don't have specific uses in mind, but I've hit issues where generics don't work as they should too many times. I'm also not going to bet anything on specialization getting implemented soon. So the current approach, which allows all expected types to implement |
@newpavlov could you resolve the conflicts please? Lets merge this! |
@dhardy Done. |
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.
Just one thing:
[RngCore
] and [CryptoRng
] should recommend usage of [impl_try_rng_from_rng_core
] and [impl_try_crypto_rng_from_crypto_rng
] respectively in their documentation.
I've updated the I am still not fully convinced on usefulness of After merging this PR, I would like to create a PR which would fix formatting and Clippy warnings. It's likely to create a bunch of conflicts in existing PRs, so if you plan to merge some of them in the near future, I can wait for those. |
Closes #1418.