Skip to content

Conversation

@newpavlov
Copy link
Member

@newpavlov newpavlov commented Nov 24, 2025

The type implements RngCore/CryptoRng traits by unwrapping potential errors. It could be useful for users who want to use the RngCore trait, do not care about potential (extremely unlikely errorr) errors, and fine with the panicking behavior.

The rand_core::UnwrapErr wrapper is not used to simplify the type initialization (just UnwrappingSysRng vs. UnwrappingSysRng::default() or UnwrapErr(SysRng)).

The intentionally long name is probably sufficient to discourage its use in favor of SysRng.

@newpavlov newpavlov requested review from dhardy and josephlr November 24, 2025 11:53
@newpavlov
Copy link
Member Author

I think UnwrappingSysRng is a bit more correct than UnwrappedSysRng since it's "an RNG which unwraps" and not "an unwrapped RNG". Plus, it's one char longer.

Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

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

I think we can show users how to use an unwrapping version of SysRng without introducing a new type.

/// [`rand::rngs::UnwrappingSysRng`]: https://docs.rs/rand/latest/rand/rngs/struct.UnwrappingSysRng.html
/// [`RngCore`]: rand_core::RngCore
#[derive(Clone, Copy, Debug, Default)]
pub struct UnwrappingSysRng;
Copy link
Member

Choose a reason for hiding this comment

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

Personally, I'm not a fan of introducing another type which is just "SysRng but we unwrap all errors".

Currently, there are two ways to already do this with rand_core (which is entirely exported by this crate):

  • use getrandom::{SysRng, rand_core::TryRngCore};
    
    let mut rng = SysRng.unwrap_err();
  • use getrandom::{SysRng, rand_core::UnwrapErr};
    
    let mut rng = UnwrapErr(SysRng);

I don't think we need to add a third way, especially if (as you say) we recommend using SysRng instead of UnwrappingSysRng. Also, the two existing methods produce the same type (UnwrapErr<SysRng>), while this approach would add a new type.

I think we should instead update the docstring for SysRng to:

  • Have the initial usage examples use [TryRngCore] without unwraping the error (like you already have)
  • Include an additional example section on how someone might use this with RngCore. Would look something like:
## Use with [`RngCore`]

Unlike the use of [`TryRngCore`] above, the [`RngCore`] trait does not allow returning
an error type. While it is possible for [`SysRng`]/[`fill`] to fail, this is usually
uncommon on most platforms (see [link to main crate docs]). For this reason, users may
want to wrap [`SysRng`] with [`rand_core::UnwrapErr`], to automatically unwrap the unlikely
errors.

```rust
use getrandom::{SysRng, rand_core::{RngCore, UnwrapErr}};

let x: u32 = UnwrapErr(SysRng).next_u32();
let y: u64 = UnwrapErr(SysRng).next_u64();
```

This can also be done via the [`TryRngCore::unwrap_err()`] method as
`let mut rng = SysRng.unwrap_err();`

Copy link
Member Author

Choose a reason for hiding this comment

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

I wouldn't say we have "two ways" right now. They are doing the same thing, but expressed differently. Following your classification we would have a bunch of other "different" ways such as UnwrapErr::<SysRng>::default().

The main rationale for the additional type is that in practice the unwrapped variant probably will be used much more often than SysRng. While I think we should nudge users towards SysRng, I don't think we should unnecessarily annoy them.

The UnwrapErr(SysRng) is quite inconvenient to use because you have to import two separate items and it looks worse in code because it can contain both UnwrapErr(SysRng) and UnwrapErr<SysRng>. Granted, it's a small papercut, but a papercut nevertheless.

I don't think UnwrappingSysRng will cause any issues or confusion in practice. Users are likely to use it without even being aware about UnwrapErr existence and it would "just work". Scenarios in which type conflicts between UnwrappingSysRng and UnwrapErr(SysRng) could happen are highly unlikely in my opinion.

Copy link
Member

Choose a reason for hiding this comment

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

The main rationale for the additional type is that in practice the unwrapped variant probably will be used much more often than SysRng.

By users of rand, probably yes. But when it comes to direct users of getrandom I'm much less sure.

But even for rand, I don't know if we want this. Using UnwrapErr<SysRng> is not that unergonomic and I suspect will not be that common.

But I may be wrong. Which in this case is fine since there is no reason this could not be added in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

I suspect will not be that common.

It looks like OsRng has plenty of uses in practice and on the first glance most of them use it in the panicking mode.

Which in this case is fine since there is no reason this could not be added in the future.

It's likely to result in an annoying mix of UnwrapErr<SysRng> and UnwrappingSysRng in downstream crates. I think we either should introduce UnwrappingSysRng right away or stick with UnwrapErr<SysRng>.

Copy link
Member

Choose a reason for hiding this comment

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

Some of those uses are ancient, as evidenced by usage of OsRng::new().

Also, basically all of these uses are just constructing an instance of OsRng for local usage, so this would be replaced with SysRng.unwrap_err(), not UnwrapErr<SysRng>.

I wonder if we should make unwrap_err an inherent fn?

///
/// `UnwrappingSysRng` implements [`RngCore`]:
/// ```
/// use getrandom::{rand_core::RngCore, UnwrappingSysRng};
Copy link
Member

Choose a reason for hiding this comment

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

Nit: rustdoc formats this as:

Suggested change
/// use getrandom::{rand_core::RngCore, UnwrappingSysRng};
/// use getrandom::{UnwrappingSysRng, rand_core::RngCore};

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