Skip to content

Commit 0fba940

Browse files
authored
rand_core: add blanket impl of TryRngCore for RngCore (#1499)
This PR removes the hacky `impl_try_rng_from_rng_core` and `impl_try_crypto_rng_from_crypto_rng` macros and replaces them with blanket impls of `TryRngCore` for `RngCore` and `TryCryptoRng` for `CryptoRng`. This change means that `TryRngCore`/`TryCryptoRng` no longer can have blanket impls for `&mut R` and `Box<R>`. But I think it should be tolerable since most users will be using `RngCore`/`CryptoRng`, which have blanket impl for `DerefMut` (it covers both `&mut R` and `Box<R>`).
1 parent 9c2787d commit 0fba940

17 files changed

+75
-184
lines changed

benches/benches/seq_choose.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ criterion_main!(benches);
2020

2121
pub fn bench(c: &mut Criterion) {
2222
c.bench_function("seq_slice_choose_1_of_100", |b| {
23-
let mut rng = Pcg32::from_rng(thread_rng());
23+
let mut rng = Pcg32::from_rng(&mut thread_rng());
2424
let mut buf = [0i32; 100];
2525
rng.fill(&mut buf);
2626
let x = black_box(&mut buf);
@@ -32,7 +32,7 @@ pub fn bench(c: &mut Criterion) {
3232
for (amount, len) in lens {
3333
let name = format!("seq_slice_choose_multiple_{}_of_{}", amount, len);
3434
c.bench_function(name.as_str(), |b| {
35-
let mut rng = Pcg32::from_rng(thread_rng());
35+
let mut rng = Pcg32::from_rng(&mut thread_rng());
3636
let mut buf = [0i32; 1000];
3737
rng.fill(&mut buf);
3838
let x = black_box(&buf[..len]);
@@ -53,15 +53,15 @@ pub fn bench(c: &mut Criterion) {
5353
}
5454

5555
c.bench_function("seq_iter_choose_multiple_10_of_100", |b| {
56-
let mut rng = Pcg32::from_rng(thread_rng());
56+
let mut rng = Pcg32::from_rng(&mut thread_rng());
5757
let mut buf = [0i32; 100];
5858
rng.fill(&mut buf);
5959
let x = black_box(&buf);
6060
b.iter(|| x.iter().cloned().choose_multiple(&mut rng, 10))
6161
});
6262

6363
c.bench_function("seq_iter_choose_multiple_fill_10_of_100", |b| {
64-
let mut rng = Pcg32::from_rng(thread_rng());
64+
let mut rng = Pcg32::from_rng(&mut thread_rng());
6565
let mut buf = [0i32; 100];
6666
rng.fill(&mut buf);
6767
let x = black_box(&buf);

benches/benches/shuffle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ criterion_main!(benches);
2020

2121
pub fn bench(c: &mut Criterion) {
2222
c.bench_function("seq_shuffle_100", |b| {
23-
let mut rng = Pcg32::from_rng(thread_rng());
23+
let mut rng = Pcg32::from_rng(&mut thread_rng());
2424
let mut buf = [0i32; 100];
2525
rng.fill(&mut buf);
2626
let x = black_box(&mut buf);

benches/benches/uniform.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const N_RESAMPLES: usize = 10_000;
2323
macro_rules! sample {
2424
($R:ty, $T:ty, $U:ty, $g:expr) => {
2525
$g.bench_function(BenchmarkId::new(stringify!($R), "single"), |b| {
26-
let mut rng = <$R>::from_rng(thread_rng());
26+
let mut rng = <$R>::from_rng(&mut thread_rng());
2727
let x = rng.random::<$U>();
2828
let bits = (<$T>::BITS / 2);
2929
let mask = (1 as $U).wrapping_neg() >> bits;
@@ -35,7 +35,7 @@ macro_rules! sample {
3535
});
3636

3737
$g.bench_function(BenchmarkId::new(stringify!($R), "distr"), |b| {
38-
let mut rng = <$R>::from_rng(thread_rng());
38+
let mut rng = <$R>::from_rng(&mut thread_rng());
3939
let x = rng.random::<$U>();
4040
let bits = (<$T>::BITS / 2);
4141
let mask = (1 as $U).wrapping_neg() >> bits;

benches/benches/uniform_float.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const N_RESAMPLES: usize = 10_000;
2727
macro_rules! single_random {
2828
($R:ty, $T:ty, $g:expr) => {
2929
$g.bench_function(BenchmarkId::new(stringify!($T), stringify!($R)), |b| {
30-
let mut rng = <$R>::from_rng(thread_rng());
30+
let mut rng = <$R>::from_rng(&mut thread_rng());
3131
let (mut low, mut high);
3232
loop {
3333
low = <$T>::from_bits(rng.random());
@@ -63,7 +63,7 @@ fn single_random(c: &mut Criterion) {
6363
macro_rules! distr_random {
6464
($R:ty, $T:ty, $g:expr) => {
6565
$g.bench_function(BenchmarkId::new(stringify!($T), stringify!($R)), |b| {
66-
let mut rng = <$R>::from_rng(thread_rng());
66+
let mut rng = <$R>::from_rng(&mut thread_rng());
6767
let dist = loop {
6868
let low = <$T>::from_bits(rng.random());
6969
let high = <$T>::from_bits(rng.random());

benches/benches/weighted.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn bench(c: &mut Criterion) {
5353
c.bench_function(name.as_str(), |b| {
5454
let length = black_box(length);
5555
let amount = black_box(amount);
56-
let mut rng = SmallRng::from_rng(thread_rng());
56+
let mut rng = SmallRng::from_rng(&mut thread_rng());
5757
b.iter(|| sample_weighted(&mut rng, length, |idx| (1 + (idx % 100)) as u32, amount))
5858
});
5959
}

rand_chacha/src/chacha.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,6 @@ macro_rules! chacha_impl {
257257

258258
impl CryptoRng for $ChaChaXRng {}
259259

260-
rand_core::impl_try_crypto_rng_from_crypto_rng!($ChaChaXRng);
261-
262260
impl From<$ChaChaXCore> for $ChaChaXRng {
263261
fn from(core: $ChaChaXCore) -> Self {
264262
$ChaChaXRng {

rand_core/src/blanket_impls.rs

Lines changed: 0 additions & 88 deletions
This file was deleted.

rand_core/src/block.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,12 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
250250
}
251251

252252
#[inline(always)]
253-
fn from_rng(rng: impl RngCore) -> Self {
253+
fn from_rng(rng: &mut impl RngCore) -> Self {
254254
Self::new(R::from_rng(rng))
255255
}
256256

257257
#[inline(always)]
258-
fn try_from_rng<S: TryRngCore>(rng: S) -> Result<Self, S::Error> {
258+
fn try_from_rng<S: TryRngCore>(rng: &mut S) -> Result<Self, S::Error> {
259259
R::try_from_rng(rng).map(Self::new)
260260
}
261261
}
@@ -415,12 +415,12 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
415415
}
416416

417417
#[inline(always)]
418-
fn from_rng(rng: impl RngCore) -> Self {
418+
fn from_rng(rng: &mut impl RngCore) -> Self {
419419
Self::new(R::from_rng(rng))
420420
}
421421

422422
#[inline(always)]
423-
fn try_from_rng<S: TryRngCore>(rng: S) -> Result<Self, S::Error> {
423+
fn try_from_rng<S: TryRngCore>(rng: &mut S) -> Result<Self, S::Error> {
424424
R::try_from_rng(rng).map(Self::new)
425425
}
426426
}

rand_core/src/impls.rs

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -160,60 +160,6 @@ pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
160160
u64::from_le_bytes(buf)
161161
}
162162

163-
/// Implement [`TryRngCore`][crate::TryRngCore] for a type implementing [`RngCore`].
164-
///
165-
/// Ideally, `rand_core` would define blanket impls for this, but they conflict with blanket impls
166-
/// for `&mut R` and `Box<R>`, so until specialziation is stabilized, implementer crates
167-
/// have to implement `TryRngCore` directly.
168-
#[macro_export]
169-
macro_rules! impl_try_rng_from_rng_core {
170-
($t:ty) => {
171-
impl $crate::TryRngCore for $t {
172-
type Error = core::convert::Infallible;
173-
174-
#[inline]
175-
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
176-
Ok($crate::RngCore::next_u32(self))
177-
}
178-
179-
#[inline]
180-
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
181-
Ok($crate::RngCore::next_u64(self))
182-
}
183-
184-
#[inline]
185-
fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
186-
$crate::RngCore::fill_bytes(self, dst);
187-
Ok(())
188-
}
189-
}
190-
};
191-
}
192-
193-
/// Implement [`TryCryptoRng`] and [`TryRngCore`] for a type implementing [`CryptoRng`].
194-
///
195-
/// Ideally, `rand_core` would define blanket impls for this, but they conflict with blanket impls
196-
/// for `&mut R` and `Box<R>`, so until specialziation is stabilized, implementer crates
197-
/// have to implement `TryRngCore` and `TryCryptoRng` directly.
198-
///
199-
/// [`TryCryptoRng`]: crate::TryCryptoRng
200-
/// [`TryRngCore`]: crate::TryRngCore
201-
/// [`CryptoRng`]: crate::CryptoRng
202-
#[macro_export]
203-
macro_rules! impl_try_crypto_rng_from_crypto_rng {
204-
($t:ty) => {
205-
$crate::impl_try_rng_from_rng_core!($t);
206-
207-
impl $crate::TryCryptoRng for $t {}
208-
209-
/// Check at compile time that `$t` implements `CryptoRng`
210-
const _: () = {
211-
const fn check_crypto_rng_impl<T: $crate::CryptoRng>() {}
212-
check_crypto_rng_impl::<$t>();
213-
};
214-
};
215-
}
216-
217163
#[cfg(test)]
218164
mod test {
219165
use super::*;

0 commit comments

Comments
 (0)