Skip to content

Commit 4172c6e

Browse files
committed
BlockRngCore: make item type an associated type
1 parent 6e02bc0 commit 4172c6e

File tree

6 files changed

+47
-40
lines changed

6 files changed

+47
-40
lines changed

rand-core/src/impls.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! to/from byte sequences, and since its purpose is reproducibility,
2020
//! non-reproducible sources (e.g. `OsRng`) need not bother with it.
2121
22+
use core::convert::AsRef;
2223
use core::intrinsics::transmute;
2324
use core::ptr::copy_nonoverlapping;
2425
use core::{fmt, slice};
@@ -183,14 +184,14 @@ pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
183184
/// [`RngCore`]: ../RngCore.t.html
184185
/// [`SeedableRng`]: ../SeedableRng.t.html
185186
#[derive(Clone)]
186-
pub struct BlockRng<T, R: BlockRngCore<T>> {
187+
pub struct BlockRng<R: BlockRngCore> {
187188
pub core: R,
188189
pub results: R::Results,
189190
pub index: usize,
190191
}
191192

192193
// Custom Debug implementation that does not expose the contents of `results`.
193-
impl<T, R: BlockRngCore<T> + fmt::Debug> fmt::Debug for BlockRng<T, R> {
194+
impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng<R> {
194195
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
195196
fmt.debug_struct("BlockRng")
196197
.field("core", &self.core)
@@ -200,7 +201,9 @@ impl<T, R: BlockRngCore<T> + fmt::Debug> fmt::Debug for BlockRng<T, R> {
200201
}
201202
}
202203

203-
impl<R: BlockRngCore<u32>> RngCore for BlockRng<u32, R> {
204+
impl<R: BlockRngCore<Item=u32>> RngCore for BlockRng<R>
205+
where <R as BlockRngCore>::Results: AsRef<[u32]>
206+
{
204207
#[inline(always)]
205208
fn next_u32(&mut self) -> u32 {
206209
if self.index >= self.results.as_ref().len() {
@@ -308,7 +311,7 @@ impl<R: BlockRngCore<u32>> RngCore for BlockRng<u32, R> {
308311
}
309312
}
310313

311-
impl<R: BlockRngCore<u32> + SeedableRng> SeedableRng for BlockRng<u32, R> {
314+
impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
312315
type Seed = R::Seed;
313316

314317
fn from_seed(seed: Self::Seed) -> Self {
@@ -330,6 +333,6 @@ impl<R: BlockRngCore<u32> + SeedableRng> SeedableRng for BlockRng<u32, R> {
330333
}
331334
}
332335

333-
impl<T, R: BlockRngCore<T> + CryptoRng> CryptoRng for BlockRng<T, R> {}
336+
impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
334337

335338
// TODO: implement tests for the above

rand-core/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ pub trait RngCore {
200200
/// // Final RNG.
201201
/// type MyRng = BlockRng<u32, MyRngCore>;
202202
/// ```
203-
pub trait BlockRngCore<T>: Sized {
203+
pub trait BlockRngCore: Sized {
204+
/// Results element type, e.g. `u32`.
205+
type Item;
206+
204207
/// Results type. This is the 'block' an RNG implementing `BlockRngCore`
205208
/// generates, which will usually be an array like `[u32; 16]`.
206-
type Results: AsRef<[T]> + Default;
209+
type Results: AsRef<[Self::Item]> + Default;
207210

208211
/// Generate a new block of results.
209212
fn generate(&mut self, results: &mut Self::Results);

src/prng/chacha.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const STATE_WORDS: usize = 16;
6363
///
6464
/// [`set_rounds`]: #method.set_counter
6565
#[derive(Clone, Debug)]
66-
pub struct ChaChaRng(BlockRng<u32, ChaChaCore>);
66+
pub struct ChaChaRng(BlockRng<ChaChaCore>);
6767

6868
impl RngCore for ChaChaRng {
6969
#[inline]
@@ -91,11 +91,11 @@ impl SeedableRng for ChaChaRng {
9191
type Seed = <ChaChaCore as SeedableRng>::Seed;
9292

9393
fn from_seed(seed: Self::Seed) -> Self {
94-
ChaChaRng(BlockRng::<u32, ChaChaCore>::from_seed(seed))
94+
ChaChaRng(BlockRng::<ChaChaCore>::from_seed(seed))
9595
}
9696

9797
fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
98-
BlockRng::<u32, ChaChaCore>::from_rng(rng).map(|rng| ChaChaRng(rng))
98+
BlockRng::<ChaChaCore>::from_rng(rng).map(|rng| ChaChaRng(rng))
9999
}
100100
}
101101

@@ -219,7 +219,8 @@ macro_rules! double_round{
219219
}}
220220
}
221221

222-
impl BlockRngCore<u32> for ChaChaCore {
222+
impl BlockRngCore for ChaChaCore {
223+
type Item = u32;
223224
type Results = [u32; STATE_WORDS];
224225

225226
fn generate(&mut self, results: &mut Self::Results) {

src/prng/hc128.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv
6262
/// [5]: Internet Engineering Task Force (Februari 2015),
6363
/// ["Prohibiting RC4 Cipher Suites"](https://tools.ietf.org/html/rfc7465).
6464
#[derive(Clone, Debug)]
65-
pub struct Hc128Rng(BlockRng<u32, Hc128Core>);
65+
pub struct Hc128Rng(BlockRng<Hc128Core>);
6666

6767
impl RngCore for Hc128Rng {
6868
#[inline(always)]
@@ -88,11 +88,11 @@ impl SeedableRng for Hc128Rng {
8888
type Seed = <Hc128Core as SeedableRng>::Seed;
8989

9090
fn from_seed(seed: Self::Seed) -> Self {
91-
Hc128Rng(BlockRng::<u32, Hc128Core>::from_seed(seed))
91+
Hc128Rng(BlockRng::<Hc128Core>::from_seed(seed))
9292
}
9393

9494
fn from_rng<R: RngCore>(rng: &mut R) -> Result<Self, Error> {
95-
BlockRng::<u32, Hc128Core>::from_rng(rng).map(|rng| Hc128Rng(rng))
95+
BlockRng::<Hc128Core>::from_rng(rng).map(|rng| Hc128Rng(rng))
9696
}
9797
}
9898

@@ -112,7 +112,8 @@ impl fmt::Debug for Hc128Core {
112112
}
113113
}
114114

115-
impl BlockRngCore<u32> for Hc128Core {
115+
impl BlockRngCore for Hc128Core {
116+
type Item = u32;
116117
type Results = [u32; 16];
117118

118119
fn generate(&mut self, results: &mut Self::Results) {

src/reseeding.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//! A wrapper around another PRNG that reseeds it after it
1212
//! generates a certain number of random bytes.
1313
14-
use core::marker::PhantomData;
1514
use core::mem::size_of;
1615

1716
use rand_core::{RngCore, BlockRngCore, CryptoRng, SeedableRng, Error, ErrorKind};
@@ -54,12 +53,12 @@ use rand_core::impls::BlockRng;
5453
/// If handling the source error fails `ReseedingRng` will continue generating
5554
/// data from the wrapped PRNG without reseeding.
5655
#[derive(Debug)]
57-
pub struct ReseedingRng<T, R, Rsdr>(BlockRng<T, ReseedingCore<T, R, Rsdr>>)
58-
where R: BlockRngCore<T> + SeedableRng,
56+
pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)
57+
where R: BlockRngCore + SeedableRng,
5958
Rsdr: RngCore;
6059

61-
impl<T, R, Rsdr> ReseedingRng<T, R, Rsdr>
62-
where R: BlockRngCore<T> + SeedableRng,
60+
impl<R, Rsdr> ReseedingRng<R, Rsdr>
61+
where R: BlockRngCore + SeedableRng,
6362
Rsdr: RngCore
6463
{
6564
/// Create a new `ReseedingRng` with the given parameters.
@@ -70,14 +69,13 @@ where R: BlockRngCore<T> + SeedableRng,
7069
/// * `threshold`: the number of generated bytes after which to reseed the RNG.
7170
/// * `reseeder`: the RNG to use for reseeding.
7271
pub fn new(rng: R, threshold: u64, reseeder: Rsdr)
73-
-> ReseedingRng<T, R, Rsdr>
72+
-> ReseedingRng<R, Rsdr>
7473
{
7574
assert!(threshold <= ::core::i64::MAX as u64);
7675
let results_empty = R::Results::default();
7776
ReseedingRng(
7877
BlockRng {
7978
core: ReseedingCore {
80-
phantom: PhantomData,
8179
inner: rng,
8280
reseeder: reseeder,
8381
threshold: threshold as i64,
@@ -97,8 +95,9 @@ where R: BlockRngCore<T> + SeedableRng,
9795

9896
// TODO: this should be implemented for any type where the inner type
9997
// implements RngCore, but we can't specify that because ReseedingCore is private
100-
impl<R, Rsdr: RngCore> RngCore for ReseedingRng<u32, R, Rsdr>
101-
where R: BlockRngCore<u32> + SeedableRng
98+
impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr>
99+
where R: BlockRngCore<Item = u32> + SeedableRng,
100+
<R as BlockRngCore>::Results: AsRef<[u32]>
102101
{
103102
#[inline(always)]
104103
fn next_u32(&mut self) -> u32 {
@@ -119,24 +118,24 @@ where R: BlockRngCore<u32> + SeedableRng
119118
}
120119
}
121120

122-
impl<T, R, Rsdr> CryptoRng for ReseedingRng<T, R, Rsdr>
123-
where R: BlockRngCore<T> + SeedableRng + CryptoRng,
121+
impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
122+
where R: BlockRngCore + SeedableRng + CryptoRng,
124123
Rsdr: RngCore + CryptoRng {}
125124

126125
#[derive(Debug)]
127-
struct ReseedingCore<T, R, Rsdr> {
128-
phantom: PhantomData<T>, // associated with R, but not a parameter; used below
126+
struct ReseedingCore<R, Rsdr> {
129127
inner: R,
130128
reseeder: Rsdr,
131129
threshold: i64,
132130
bytes_until_reseed: i64,
133131
}
134132

135-
impl<T, R, Rsdr> BlockRngCore<T> for ReseedingCore<T, R, Rsdr>
136-
where R: BlockRngCore<T> + SeedableRng,
133+
impl<R, Rsdr> BlockRngCore for ReseedingCore<R, Rsdr>
134+
where R: BlockRngCore + SeedableRng,
137135
Rsdr: RngCore
138136
{
139-
type Results = <R as BlockRngCore<T>>::Results;
137+
type Item = <R as BlockRngCore>::Item;
138+
type Results = <R as BlockRngCore>::Results;
140139

141140
fn generate(&mut self, results: &mut Self::Results) {
142141
if self.bytes_until_reseed <= 0 {
@@ -145,14 +144,14 @@ where R: BlockRngCore<T> + SeedableRng,
145144
// returning from a non-inlined function.
146145
return self.reseed_and_generate(results);
147146
}
148-
let num_bytes = results.as_ref().len() * size_of::<T>();
147+
let num_bytes = results.as_ref().len() * size_of::<Self::Item>();
149148
self.bytes_until_reseed -= num_bytes as i64;
150149
self.inner.generate(results);
151150
}
152151
}
153152

154-
impl<T, R, Rsdr> ReseedingCore<T, R, Rsdr>
155-
where R: BlockRngCore<T> + SeedableRng,
153+
impl<R, Rsdr> ReseedingCore<R, Rsdr>
154+
where R: BlockRngCore + SeedableRng,
156155
Rsdr: RngCore
157156
{
158157
/// Reseed the internal PRNG.
@@ -165,7 +164,7 @@ where R: BlockRngCore<T> + SeedableRng,
165164

166165
#[inline(never)]
167166
fn reseed_and_generate(&mut self,
168-
results: &mut <Self as BlockRngCore<T>>::Results)
167+
results: &mut <Self as BlockRngCore>::Results)
169168
{
170169
trace!("Reseeding RNG after {} generated bytes",
171170
self.threshold - self.bytes_until_reseed);
@@ -182,14 +181,14 @@ where R: BlockRngCore<T> + SeedableRng,
182181
self.threshold
183182
};
184183

185-
let num_bytes = results.as_ref().len() * size_of::<T>();
184+
let num_bytes = results.as_ref().len() * size_of::<<R as BlockRngCore>::Item>();
186185
self.bytes_until_reseed = threshold - num_bytes as i64;
187186
self.inner.generate(results);
188187
}
189188
}
190189

191-
impl<T, R, Rsdr> CryptoRng for ReseedingCore<T, R, Rsdr>
192-
where R: BlockRngCore<T> + SeedableRng + CryptoRng,
190+
impl<R, Rsdr> CryptoRng for ReseedingCore<R, Rsdr>
191+
where R: BlockRngCore + SeedableRng + CryptoRng,
193192
Rsdr: RngCore + CryptoRng {}
194193

195194
#[cfg(test)]

src/thread_rng.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 32*1024*1024; // 32 MiB
3232
/// [`thread_rng`]: fn.thread_rng.html
3333
#[derive(Clone, Debug)]
3434
pub struct ThreadRng {
35-
rng: Rc<RefCell<ReseedingRng<u32, Hc128Core, EntropyRng>>>,
35+
rng: Rc<RefCell<ReseedingRng<Hc128Core, EntropyRng>>>,
3636
}
3737

3838
thread_local!(
39-
static THREAD_RNG_KEY: Rc<RefCell<ReseedingRng<u32, Hc128Core, EntropyRng>>> = {
39+
static THREAD_RNG_KEY: Rc<RefCell<ReseedingRng<Hc128Core, EntropyRng>>> = {
4040
let mut entropy_source = EntropyRng::new();
4141
let r = Hc128Core::from_rng(&mut entropy_source).unwrap_or_else(|err|
4242
panic!("could not initialize thread_rng: {}", err));

0 commit comments

Comments
 (0)