From 01d423739cffd83bece185e89ede61dda3768a3a Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 17 Nov 2025 09:43:40 +0000 Subject: [PATCH 1/9] Simplify trait BlockRngCore: remove assoc. type Item --- src/block.rs | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/block.rs b/src/block.rs index 2cba57e0..8dce052e 100644 --- a/src/block.rs +++ b/src/block.rs @@ -20,7 +20,6 @@ //! struct MyRngCore; //! //! impl BlockRngCore for MyRngCore { -//! type Item = u32; //! type Results = [u32; 16]; //! //! fn generate(&mut self, results: &mut Self::Results) { @@ -55,12 +54,9 @@ use core::fmt; /// /// See the [module][crate::block] documentation for details. pub trait BlockRngCore { - /// Results element type, e.g. `u32`. - type Item; - /// Results type. This is the 'block' an RNG implementing `BlockRngCore` /// generates, which will usually be an array like `[u32; 16]`. - type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default; + type Results; /// Generate a new block of results. fn generate(&mut self, results: &mut Self::Results); @@ -114,7 +110,7 @@ pub struct BlockRng { } // Custom Debug implementation that does not expose the contents of `results`. -impl fmt::Debug for BlockRng { +impl + fmt::Debug> fmt::Debug for BlockRng { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng") .field("core", &self.core) @@ -124,16 +120,15 @@ impl fmt::Debug for BlockRng { } } -impl BlockRng { +impl> BlockRng { /// Create a new `BlockRng` from an existing RNG implementing /// `BlockRngCore`. Results will be generated on first use. #[inline] pub fn new(core: R) -> BlockRng { - let results_empty = R::Results::default(); BlockRng { core, - index: results_empty.as_ref().len(), - results: results_empty, + index: N, + results: [0; N], } } @@ -164,7 +159,7 @@ impl BlockRng { } } -impl> RngCore for BlockRng { +impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { if self.index >= self.results.as_ref().len() { @@ -217,7 +212,9 @@ impl> RngCore for BlockRng { } } -impl SeedableRng for BlockRng { +impl + SeedableRng> SeedableRng + for BlockRng +{ type Seed = R::Seed; #[inline(always)] @@ -241,7 +238,7 @@ impl SeedableRng for BlockRng { } } -impl> CryptoRng for BlockRng {} +impl> CryptoRng for BlockRng {} /// A wrapper type implementing [`RngCore`] for some type implementing /// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement @@ -273,7 +270,9 @@ pub struct BlockRng64 { } // Custom Debug implementation that does not expose the contents of `results`. -impl fmt::Debug for BlockRng64 { +impl + fmt::Debug> fmt::Debug + for BlockRng64 +{ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng64") .field("core", &self.core) @@ -284,12 +283,12 @@ impl fmt::Debug for BlockRng64 { } } -impl BlockRng64 { +impl> BlockRng64 { /// Create a new `BlockRng` from an existing RNG implementing /// `BlockRngCore`. Results will be generated on first use. #[inline] pub fn new(core: R) -> BlockRng64 { - let results_empty = R::Results::default(); + let results_empty = [0; N]; BlockRng64 { core, index: results_empty.as_ref().len(), @@ -327,7 +326,7 @@ impl BlockRng64 { } } -impl> RngCore for BlockRng64 { +impl> RngCore for BlockRng64 { #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; @@ -379,7 +378,9 @@ impl> RngCore for BlockRng64 { } } -impl SeedableRng for BlockRng64 { +impl + SeedableRng> SeedableRng + for BlockRng64 +{ type Seed = R::Seed; #[inline(always)] @@ -403,7 +404,7 @@ impl SeedableRng for BlockRng64 { } } -impl> CryptoRng for BlockRng64 {} +impl> CryptoRng for BlockRng64 {} #[cfg(test)] mod test { @@ -416,7 +417,6 @@ mod test { } impl BlockRngCore for DummyRng { - type Item = u32; type Results = [u32; 16]; fn generate(&mut self, results: &mut Self::Results) { @@ -467,7 +467,6 @@ mod test { } impl BlockRngCore for DummyRng64 { - type Item = u64; type Results = [u64; 8]; fn generate(&mut self, results: &mut Self::Results) { From e34c1f3215ba105e0fab5a1359e26058433b4968 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 17 Nov 2025 10:08:30 +0000 Subject: [PATCH 2/9] Allow *any* unused code in doc tests From 977f74e24910545371a8c4b1899f816c04f4deac Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 17 Nov 2025 10:17:27 +0000 Subject: [PATCH 3/9] Rename BlockRngCore -> Generator --- src/block.rs | 78 +++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/block.rs b/src/block.rs index 8dce052e..5814eff8 100644 --- a/src/block.rs +++ b/src/block.rs @@ -1,6 +1,6 @@ -//! The `BlockRngCore` trait and implementation helpers +//! The `Generator` trait and implementation helpers //! -//! The [`BlockRngCore`] trait exists to assist in the implementation of RNGs +//! The [`Generator`] trait exists to assist in the implementation of RNGs //! which generate a block of data in a cache instead of returning generated //! values directly. //! @@ -15,11 +15,11 @@ //! //! ```no_run //! use rand_core::{RngCore, SeedableRng}; -//! use rand_core::block::{BlockRngCore, BlockRng}; +//! use rand_core::block::{Generator, BlockRng}; //! //! struct MyRngCore; //! -//! impl BlockRngCore for MyRngCore { +//! impl Generator for MyRngCore { //! type Results = [u32; 16]; //! //! fn generate(&mut self, results: &mut Self::Results) { @@ -34,26 +34,22 @@ //! } //! } //! -//! // optionally, also implement CryptoBlockRng for MyRngCore +//! // optionally, also implement CryptoGenerator for MyRngCore //! //! // Final RNG. //! let mut rng = BlockRng::::seed_from_u64(0); //! println!("First value: {}", rng.next_u32()); //! ``` //! -//! [`BlockRngCore`]: crate::block::BlockRngCore +//! [`Generator`]: crate::block::Generator //! [`fill_bytes`]: RngCore::fill_bytes use crate::le::fill_via_chunks; use crate::{CryptoRng, RngCore, SeedableRng, TryRngCore}; use core::fmt; -/// A trait for RNGs which do not generate random numbers individually, but in -/// blocks (typically `[u32; N]`). This technique is commonly used by -/// cryptographic RNGs to improve performance. -/// -/// See the [module][crate::block] documentation for details. -pub trait BlockRngCore { +/// A random (block) generator +pub trait Generator { /// Results type. This is the 'block' an RNG implementing `BlockRngCore` /// generates, which will usually be an array like `[u32; 16]`. type Results; @@ -62,14 +58,20 @@ pub trait BlockRngCore { fn generate(&mut self, results: &mut Self::Results); } -/// A marker trait used to indicate that an [`RngCore`] implementation is -/// supposed to be cryptographically secure. +/// A cryptographically secure generator +/// +/// This is a marker trait used to indicate that a [`Generator`] implementation +/// is supposed to be cryptographically secure. +/// +/// Mock generators should not implement this trait *except* under a +/// `#[cfg(test)]` attribute to ensure that mock "crypto" generators cannot be +/// used in production. /// /// See [`CryptoRng`] docs for more information. -pub trait CryptoBlockRng: BlockRngCore {} +pub trait CryptoGenerator: Generator {} /// A wrapper type implementing [`RngCore`] for some type implementing -/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement +/// [`Generator`] with `u32` array buffer; i.e. this can be used to implement /// a full RNG from just a `generate` function. /// /// The `core` field may be accessed directly but the results buffer may not. @@ -82,7 +84,7 @@ pub trait CryptoBlockRng: BlockRngCore {} /// /// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods /// reading values from the results buffer, as well as -/// calling [`BlockRngCore::generate`] directly on the output array when +/// calling [`Generator::generate`] directly on the output array when /// [`fill_bytes`] is called on a large array. These methods also handle /// the bookkeeping of when to generate a new batch of values. /// @@ -102,7 +104,7 @@ pub trait CryptoBlockRng: BlockRngCore {} /// [`next_u64`]: RngCore::next_u64 /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] -pub struct BlockRng { +pub struct BlockRng { results: R::Results, index: usize, /// The *core* part of the RNG, implementing the `generate` function. @@ -110,7 +112,7 @@ pub struct BlockRng { } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng { +impl + fmt::Debug> fmt::Debug for BlockRng { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng") .field("core", &self.core) @@ -120,9 +122,9 @@ impl + fmt::Debug> fmt::Debu } } -impl> BlockRng { +impl> BlockRng { /// Create a new `BlockRng` from an existing RNG implementing - /// `BlockRngCore`. Results will be generated on first use. + /// `Generator`. Results will be generated on first use. #[inline] pub fn new(core: R) -> BlockRng { BlockRng { @@ -159,7 +161,7 @@ impl> BlockRng { } } -impl> RngCore for BlockRng { +impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { if self.index >= self.results.as_ref().len() { @@ -212,9 +214,7 @@ impl> RngCore for BlockRng + SeedableRng> SeedableRng - for BlockRng -{ +impl + SeedableRng> SeedableRng for BlockRng { type Seed = R::Seed; #[inline(always)] @@ -238,10 +238,10 @@ impl + SeedableRng> Seedable } } -impl> CryptoRng for BlockRng {} +impl> CryptoRng for BlockRng {} /// A wrapper type implementing [`RngCore`] for some type implementing -/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement +/// [`Generator`] with `u64` array buffer; i.e. this can be used to implement /// a full RNG from just a `generate` function. /// /// This is similar to [`BlockRng`], but specialized for algorithms that operate @@ -261,7 +261,7 @@ impl> CryptoRng for BlockR /// [`next_u64`]: RngCore::next_u64 /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] -pub struct BlockRng64 { +pub struct BlockRng64 { results: R::Results, index: usize, half_used: bool, // true if only half of the previous result is used @@ -270,9 +270,7 @@ pub struct BlockRng64 { } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug - for BlockRng64 -{ +impl + fmt::Debug> fmt::Debug for BlockRng64 { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng64") .field("core", &self.core) @@ -283,9 +281,9 @@ impl + fmt::Debug> fmt::Debu } } -impl> BlockRng64 { +impl> BlockRng64 { /// Create a new `BlockRng` from an existing RNG implementing - /// `BlockRngCore`. Results will be generated on first use. + /// `Generator`. Results will be generated on first use. #[inline] pub fn new(core: R) -> BlockRng64 { let results_empty = [0; N]; @@ -326,7 +324,7 @@ impl> BlockRng64 { } } -impl> RngCore for BlockRng64 { +impl> RngCore for BlockRng64 { #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; @@ -378,9 +376,7 @@ impl> RngCore for BlockRng64 } } -impl + SeedableRng> SeedableRng - for BlockRng64 -{ +impl + SeedableRng> SeedableRng for BlockRng64 { type Seed = R::Seed; #[inline(always)] @@ -404,11 +400,11 @@ impl + SeedableRng> Seedable } } -impl> CryptoRng for BlockRng64 {} +impl> CryptoRng for BlockRng64 {} #[cfg(test)] mod test { - use crate::block::{BlockRng, BlockRng64, BlockRngCore}; + use crate::block::{BlockRng, BlockRng64, Generator}; use crate::{RngCore, SeedableRng}; #[derive(Debug, Clone)] @@ -416,7 +412,7 @@ mod test { counter: u32, } - impl BlockRngCore for DummyRng { + impl Generator for DummyRng { type Results = [u32; 16]; fn generate(&mut self, results: &mut Self::Results) { @@ -466,7 +462,7 @@ mod test { counter: u64, } - impl BlockRngCore for DummyRng64 { + impl Generator for DummyRng64 { type Results = [u64; 8]; fn generate(&mut self, results: &mut Self::Results) { From ed22701baec3044ae31ef5b55420ab0e4a760fb7 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Sun, 30 Nov 2025 11:33:19 +0000 Subject: [PATCH 4/9] Rename Generator::Results -> Output --- src/block.rs | 57 +++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/block.rs b/src/block.rs index 5814eff8..afb38d73 100644 --- a/src/block.rs +++ b/src/block.rs @@ -20,9 +20,9 @@ //! struct MyRngCore; //! //! impl Generator for MyRngCore { -//! type Results = [u32; 16]; +//! type Output = [u32; 16]; //! -//! fn generate(&mut self, results: &mut Self::Results) { +//! fn generate(&mut self, output: &mut Self::Output) { //! unimplemented!() //! } //! } @@ -50,12 +50,15 @@ use core::fmt; /// A random (block) generator pub trait Generator { - /// Results type. This is the 'block' an RNG implementing `BlockRngCore` - /// generates, which will usually be an array like `[u32; 16]`. - type Results; + /// The output type. + /// + /// For use with [`rand_core::block`](crate::block) code this must be `[u32; _]` or `[u64; _]`. + type Output; - /// Generate a new block of results. - fn generate(&mut self, results: &mut Self::Results); + /// Generate a new block of `output`. + /// + /// This must fill `output` with random data. + fn generate(&mut self, output: &mut Self::Output); } /// A cryptographically secure generator @@ -105,14 +108,14 @@ pub trait CryptoGenerator: Generator {} /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] pub struct BlockRng { - results: R::Results, + results: R::Output, index: usize, /// The *core* part of the RNG, implementing the `generate` function. pub core: R, } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng { +impl + fmt::Debug> fmt::Debug for BlockRng { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng") .field("core", &self.core) @@ -122,7 +125,7 @@ impl + fmt::Debug> fmt::Debug f } } -impl> BlockRng { +impl> BlockRng { /// Create a new `BlockRng` from an existing RNG implementing /// `Generator`. Results will be generated on first use. #[inline] @@ -161,7 +164,7 @@ impl> BlockRng { } } -impl> RngCore for BlockRng { +impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { if self.index >= self.results.as_ref().len() { @@ -214,7 +217,7 @@ impl> RngCore for BlockRng { } } -impl + SeedableRng> SeedableRng for BlockRng { +impl + SeedableRng> SeedableRng for BlockRng { type Seed = R::Seed; #[inline(always)] @@ -238,7 +241,7 @@ impl + SeedableRng> SeedableRng } } -impl> CryptoRng for BlockRng {} +impl> CryptoRng for BlockRng {} /// A wrapper type implementing [`RngCore`] for some type implementing /// [`Generator`] with `u64` array buffer; i.e. this can be used to implement @@ -262,7 +265,7 @@ impl> CryptoRng for Block /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] pub struct BlockRng64 { - results: R::Results, + results: R::Output, index: usize, half_used: bool, // true if only half of the previous result is used /// The *core* part of the RNG, implementing the `generate` function. @@ -270,7 +273,7 @@ pub struct BlockRng64 { } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng64 { +impl + fmt::Debug> fmt::Debug for BlockRng64 { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng64") .field("core", &self.core) @@ -281,7 +284,7 @@ impl + fmt::Debug> fmt::Debug f } } -impl> BlockRng64 { +impl> BlockRng64 { /// Create a new `BlockRng` from an existing RNG implementing /// `Generator`. Results will be generated on first use. #[inline] @@ -324,7 +327,7 @@ impl> BlockRng64 { } } -impl> RngCore for BlockRng64 { +impl> RngCore for BlockRng64 { #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; @@ -376,7 +379,7 @@ impl> RngCore for BlockRng64 } } -impl + SeedableRng> SeedableRng for BlockRng64 { +impl + SeedableRng> SeedableRng for BlockRng64 { type Seed = R::Seed; #[inline(always)] @@ -400,7 +403,7 @@ impl + SeedableRng> SeedableRng } } -impl> CryptoRng for BlockRng64 {} +impl> CryptoRng for BlockRng64 {} #[cfg(test)] mod test { @@ -413,11 +416,11 @@ mod test { } impl Generator for DummyRng { - type Results = [u32; 16]; + type Output = [u32; 16]; - fn generate(&mut self, results: &mut Self::Results) { - for r in results { - *r = self.counter; + fn generate(&mut self, output: &mut Self::Output) { + for item in output { + *item = self.counter; self.counter = self.counter.wrapping_add(3511615421); } } @@ -463,11 +466,11 @@ mod test { } impl Generator for DummyRng64 { - type Results = [u64; 8]; + type Output = [u64; 8]; - fn generate(&mut self, results: &mut Self::Results) { - for r in results { - *r = self.counter; + fn generate(&mut self, output: &mut Self::Output) { + for item in output { + *item = self.counter; self.counter = self.counter.wrapping_add(2781463553396133981); } } From 5f5995642caf5fc888ed9dcbd9e5082c05a03695 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Sun, 30 Nov 2025 16:04:54 +0000 Subject: [PATCH 5/9] Rename R -> G: Generator --- src/block.rs | 56 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/block.rs b/src/block.rs index afb38d73..2a8fc8bd 100644 --- a/src/block.rs +++ b/src/block.rs @@ -107,15 +107,15 @@ pub trait CryptoGenerator: Generator {} /// [`next_u64`]: RngCore::next_u64 /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] -pub struct BlockRng { - results: R::Output, +pub struct BlockRng { + results: G::Output, index: usize, /// The *core* part of the RNG, implementing the `generate` function. - pub core: R, + pub core: G, } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng { +impl + fmt::Debug> fmt::Debug for BlockRng { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng") .field("core", &self.core) @@ -125,11 +125,11 @@ impl + fmt::Debug> fmt::Debug fo } } -impl> BlockRng { +impl> BlockRng { /// Create a new `BlockRng` from an existing RNG implementing /// `Generator`. Results will be generated on first use. #[inline] - pub fn new(core: R) -> BlockRng { + pub fn new(core: G) -> BlockRng { BlockRng { core, index: N, @@ -164,7 +164,7 @@ impl> BlockRng { } } -impl> RngCore for BlockRng { +impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { if self.index >= self.results.as_ref().len() { @@ -217,31 +217,31 @@ impl> RngCore for BlockRng { } } -impl + SeedableRng> SeedableRng for BlockRng { - type Seed = R::Seed; +impl + SeedableRng> SeedableRng for BlockRng { + type Seed = G::Seed; #[inline(always)] fn from_seed(seed: Self::Seed) -> Self { - Self::new(R::from_seed(seed)) + Self::new(G::from_seed(seed)) } #[inline(always)] fn seed_from_u64(seed: u64) -> Self { - Self::new(R::seed_from_u64(seed)) + Self::new(G::seed_from_u64(seed)) } #[inline(always)] fn from_rng(rng: &mut S) -> Self { - Self::new(R::from_rng(rng)) + Self::new(G::from_rng(rng)) } #[inline(always)] fn try_from_rng(rng: &mut S) -> Result { - R::try_from_rng(rng).map(Self::new) + G::try_from_rng(rng).map(Self::new) } } -impl> CryptoRng for BlockRng {} +impl> CryptoRng for BlockRng {} /// A wrapper type implementing [`RngCore`] for some type implementing /// [`Generator`] with `u64` array buffer; i.e. this can be used to implement @@ -264,16 +264,16 @@ impl> CryptoRng for BlockR /// [`next_u64`]: RngCore::next_u64 /// [`fill_bytes`]: RngCore::fill_bytes #[derive(Clone)] -pub struct BlockRng64 { - results: R::Output, +pub struct BlockRng64 { + results: G::Output, index: usize, half_used: bool, // true if only half of the previous result is used /// The *core* part of the RNG, implementing the `generate` function. - pub core: R, + pub core: G, } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng64 { +impl + fmt::Debug> fmt::Debug for BlockRng64 { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng64") .field("core", &self.core) @@ -284,11 +284,11 @@ impl + fmt::Debug> fmt::Debug fo } } -impl> BlockRng64 { +impl> BlockRng64 { /// Create a new `BlockRng` from an existing RNG implementing /// `Generator`. Results will be generated on first use. #[inline] - pub fn new(core: R) -> BlockRng64 { + pub fn new(core: G) -> BlockRng64 { let results_empty = [0; N]; BlockRng64 { core, @@ -327,7 +327,7 @@ impl> BlockRng64 { } } -impl> RngCore for BlockRng64 { +impl> RngCore for BlockRng64 { #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; @@ -379,31 +379,31 @@ impl> RngCore for BlockRng64 } } -impl + SeedableRng> SeedableRng for BlockRng64 { - type Seed = R::Seed; +impl + SeedableRng> SeedableRng for BlockRng64 { + type Seed = G::Seed; #[inline(always)] fn from_seed(seed: Self::Seed) -> Self { - Self::new(R::from_seed(seed)) + Self::new(G::from_seed(seed)) } #[inline(always)] fn seed_from_u64(seed: u64) -> Self { - Self::new(R::seed_from_u64(seed)) + Self::new(G::seed_from_u64(seed)) } #[inline(always)] fn from_rng(rng: &mut S) -> Self { - Self::new(R::from_rng(rng)) + Self::new(G::from_rng(rng)) } #[inline(always)] fn try_from_rng(rng: &mut S) -> Result { - R::try_from_rng(rng).map(Self::new) + G::try_from_rng(rng).map(Self::new) } } -impl> CryptoRng for BlockRng64 {} +impl> CryptoRng for BlockRng64 {} #[cfg(test)] mod test { From 84c23d885c7999241de5673e7f816ca6b198e3d1 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Sun, 30 Nov 2025 16:26:26 +0000 Subject: [PATCH 6/9] BlockRng: remove bound on ::Output in Debug impl --- src/block.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/block.rs b/src/block.rs index 2a8fc8bd..79cc4811 100644 --- a/src/block.rs +++ b/src/block.rs @@ -115,11 +115,10 @@ pub struct BlockRng { } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng { +impl fmt::Debug for BlockRng { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng") .field("core", &self.core) - .field("result_len", &self.results.as_ref().len()) .field("index", &self.index) .finish() } @@ -273,11 +272,10 @@ pub struct BlockRng64 { } // Custom Debug implementation that does not expose the contents of `results`. -impl + fmt::Debug> fmt::Debug for BlockRng64 { +impl fmt::Debug for BlockRng64 { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BlockRng64") .field("core", &self.core) - .field("result_len", &self.results.as_ref().len()) .field("index", &self.index) .field("half_used", &self.half_used) .finish() From fdf3885d7754ae2a7c8d22fe15de9d18ac9bd22f Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 1 Dec 2025 14:41:09 +0000 Subject: [PATCH 7/9] Remove unnecessary calls to as_ref / as_mut --- src/block.rs | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/block.rs b/src/block.rs index 79cc4811..10c89279 100644 --- a/src/block.rs +++ b/src/block.rs @@ -150,14 +150,14 @@ impl> BlockRng { /// This will force a new set of results to be generated on next use. #[inline] pub fn reset(&mut self) { - self.index = self.results.as_ref().len(); + self.index = self.results.len(); } /// Generate a new set of results immediately, setting the index to the /// given value. #[inline] pub fn generate_and_set(&mut self, index: usize) { - assert!(index < self.results.as_ref().len()); + assert!(index < self.results.len()); self.core.generate(&mut self.results); self.index = index; } @@ -166,11 +166,11 @@ impl> BlockRng { impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { - if self.index >= self.results.as_ref().len() { + if self.index >= self.results.len() { self.generate_and_set(0); } - let value = self.results.as_ref()[self.index]; + let value = self.results[self.index]; self.index += 1; value } @@ -182,20 +182,20 @@ impl> RngCore for BlockRng { (u64::from(data[1]) << 32) | u64::from(data[0]) }; - let len = self.results.as_ref().len(); + let len = self.results.len(); let index = self.index; if index < len - 1 { self.index += 2; // Read an u64 from the current index - read_u64(self.results.as_ref(), index) + read_u64(&self.results, index) } else if index >= len { self.generate_and_set(2); - read_u64(self.results.as_ref(), 0) + read_u64(&self.results, 0) } else { - let x = u64::from(self.results.as_ref()[len - 1]); + let x = u64::from(self.results[len - 1]); self.generate_and_set(1); - let y = u64::from(self.results.as_ref()[0]); + let y = u64::from(self.results[0]); (y << 32) | x } } @@ -204,11 +204,11 @@ impl> RngCore for BlockRng { fn fill_bytes(&mut self, dest: &mut [u8]) { let mut read_len = 0; while read_len < dest.len() { - if self.index >= self.results.as_ref().len() { + if self.index >= self.results.len() { self.generate_and_set(0); } let (consumed_u32, filled_u8) = - fill_via_chunks(&self.results.as_mut()[self.index..], &mut dest[read_len..]); + fill_via_chunks(&self.results[self.index..], &mut dest[read_len..]); self.index += consumed_u32; read_len += filled_u8; @@ -290,7 +290,7 @@ impl> BlockRng64 { let results_empty = [0; N]; BlockRng64 { core, - index: results_empty.as_ref().len(), + index: results_empty.len(), half_used: false, results: results_empty, } @@ -310,7 +310,7 @@ impl> BlockRng64 { /// This will force a new set of results to be generated on next use. #[inline] pub fn reset(&mut self) { - self.index = self.results.as_ref().len(); + self.index = self.results.len(); self.half_used = false; } @@ -318,7 +318,7 @@ impl> BlockRng64 { /// given value. #[inline] pub fn generate_and_set(&mut self, index: usize) { - assert!(index < self.results.as_ref().len()); + assert!(index < self.results.len()); self.core.generate(&mut self.results); self.index = index; self.half_used = false; @@ -329,7 +329,7 @@ impl> RngCore for BlockRng64 #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; - if index >= self.results.as_ref().len() { + if index >= self.results.len() { self.core.generate(&mut self.results); self.index = 0; index = 0; @@ -342,17 +342,17 @@ impl> RngCore for BlockRng64 self.half_used = !self.half_used; self.index += self.half_used as usize; - (self.results.as_ref()[index] >> shift) as u32 + (self.results[index] >> shift) as u32 } #[inline] fn next_u64(&mut self) -> u64 { - if self.index >= self.results.as_ref().len() { + if self.index >= self.results.len() { self.core.generate(&mut self.results); self.index = 0; } - let value = self.results.as_ref()[self.index]; + let value = self.results[self.index]; self.index += 1; self.half_used = false; value @@ -363,13 +363,13 @@ impl> RngCore for BlockRng64 let mut read_len = 0; self.half_used = false; while read_len < dest.len() { - if self.index >= self.results.as_ref().len() { + if self.index >= self.results.len() { self.core.generate(&mut self.results); self.index = 0; } let (consumed_u64, filled_u8) = - fill_via_chunks(&self.results.as_mut()[self.index..], &mut dest[read_len..]); + fill_via_chunks(&self.results[self.index..], &mut dest[read_len..]); self.index += consumed_u64; read_len += filled_u8; @@ -513,23 +513,23 @@ mod test { #[test] fn blockrng64_generate_and_set() { let mut rng = BlockRng64::::from_seed([1, 2, 3, 4, 5, 6, 7, 8]); - assert_eq!(rng.index(), rng.results.as_ref().len()); + assert_eq!(rng.index(), rng.results.len()); rng.generate_and_set(5); assert_eq!(rng.index(), 5); } #[test] - #[should_panic(expected = "index < self.results.as_ref().len()")] + #[should_panic(expected = "index < self.results.len()")] fn blockrng64_generate_and_set_panic() { let mut rng = BlockRng64::::from_seed([1, 2, 3, 4, 5, 6, 7, 8]); - rng.generate_and_set(rng.results.as_ref().len()); + rng.generate_and_set(rng.results.len()); } #[test] fn blockrng_next_u64() { let mut rng = BlockRng::::from_seed([1, 2, 3, 4]); - let result_size = rng.results.as_ref().len(); + let result_size = rng.results.len(); for _i in 0..result_size / 2 - 1 { rng.next_u64(); } From 49ff793b1d0f161047d1297f0822858f42d2426f Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 1 Dec 2025 14:49:51 +0000 Subject: [PATCH 8/9] Replace usages of results.len() with N --- src/block.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/block.rs b/src/block.rs index 10c89279..c04abb61 100644 --- a/src/block.rs +++ b/src/block.rs @@ -150,14 +150,14 @@ impl> BlockRng { /// This will force a new set of results to be generated on next use. #[inline] pub fn reset(&mut self) { - self.index = self.results.len(); + self.index = N; } /// Generate a new set of results immediately, setting the index to the /// given value. #[inline] pub fn generate_and_set(&mut self, index: usize) { - assert!(index < self.results.len()); + assert!(index < N); self.core.generate(&mut self.results); self.index = index; } @@ -166,7 +166,7 @@ impl> BlockRng { impl> RngCore for BlockRng { #[inline] fn next_u32(&mut self) -> u32 { - if self.index >= self.results.len() { + if self.index >= N { self.generate_and_set(0); } @@ -182,18 +182,16 @@ impl> RngCore for BlockRng { (u64::from(data[1]) << 32) | u64::from(data[0]) }; - let len = self.results.len(); - let index = self.index; - if index < len - 1 { + if index < N - 1 { self.index += 2; // Read an u64 from the current index read_u64(&self.results, index) - } else if index >= len { + } else if index >= N { self.generate_and_set(2); read_u64(&self.results, 0) } else { - let x = u64::from(self.results[len - 1]); + let x = u64::from(self.results[N - 1]); self.generate_and_set(1); let y = u64::from(self.results[0]); (y << 32) | x @@ -204,7 +202,7 @@ impl> RngCore for BlockRng { fn fill_bytes(&mut self, dest: &mut [u8]) { let mut read_len = 0; while read_len < dest.len() { - if self.index >= self.results.len() { + if self.index >= N { self.generate_and_set(0); } let (consumed_u32, filled_u8) = @@ -287,12 +285,11 @@ impl> BlockRng64 { /// `Generator`. Results will be generated on first use. #[inline] pub fn new(core: G) -> BlockRng64 { - let results_empty = [0; N]; BlockRng64 { core, - index: results_empty.len(), + index: N, half_used: false, - results: results_empty, + results: [0; N], } } @@ -310,7 +307,7 @@ impl> BlockRng64 { /// This will force a new set of results to be generated on next use. #[inline] pub fn reset(&mut self) { - self.index = self.results.len(); + self.index = N; self.half_used = false; } @@ -318,7 +315,7 @@ impl> BlockRng64 { /// given value. #[inline] pub fn generate_and_set(&mut self, index: usize) { - assert!(index < self.results.len()); + assert!(index < N); self.core.generate(&mut self.results); self.index = index; self.half_used = false; @@ -329,7 +326,7 @@ impl> RngCore for BlockRng64 #[inline] fn next_u32(&mut self) -> u32 { let mut index = self.index - self.half_used as usize; - if index >= self.results.len() { + if index >= N { self.core.generate(&mut self.results); self.index = 0; index = 0; @@ -347,7 +344,7 @@ impl> RngCore for BlockRng64 #[inline] fn next_u64(&mut self) -> u64 { - if self.index >= self.results.len() { + if self.index >= N { self.core.generate(&mut self.results); self.index = 0; } @@ -363,7 +360,7 @@ impl> RngCore for BlockRng64 let mut read_len = 0; self.half_used = false; while read_len < dest.len() { - if self.index >= self.results.len() { + if self.index >= N { self.core.generate(&mut self.results); self.index = 0; } @@ -520,7 +517,7 @@ mod test { } #[test] - #[should_panic(expected = "index < self.results.len()")] + #[should_panic(expected = "index < N")] fn blockrng64_generate_and_set_panic() { let mut rng = BlockRng64::::from_seed([1, 2, 3, 4, 5, 6, 7, 8]); rng.generate_and_set(rng.results.len()); From 3777037cfb8fe330d396ae1b107485477ad3f8dd Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 1 Dec 2025 14:44:11 +0000 Subject: [PATCH 9/9] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f195af0..0780ced2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed dependency `getrandom` ([rand#1674]) - Removed optional dependency `serde` ([#28]) - Add `SeedableRng::fork` methods ([#17]) +- Rename trait `block::BlockRngCore` to `block::Generator` and associated type `Results` to `Output`; remove assoc. `type Item` and remove type bounds ([#26]) ### Other - Changed repository from [rust-random/rand] to [rust-random/core]. @@ -26,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [rand#1669]: https://github.com/rust-random/rand/pull/1669 [rand#1674]: https://github.com/rust-random/rand/pull/1674 [#17]: https://github.com/rust-random/rand-core/pull/17 +[#26]: https://github.com/rust-random/rand-core/pull/28 [#28]: https://github.com/rust-random/rand-core/pull/28 [rust-random/rand]: https://github.com/rust-random/rand