diff --git a/rand-core/src/error.rs b/rand-core/src/error.rs index f0219cfdff3..f4ffc56d78c 100644 --- a/rand-core/src/error.rs +++ b/rand-core/src/error.rs @@ -161,3 +161,19 @@ impl stdError for Error { self.cause.as_ref().map(|e| e.as_ref() as &stdError) } } + +/// Void error type, for use when errors are statically impossible. +#[derive(Debug)] +pub enum Void {} + +impl fmt::Display for Void { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + unreachable!() + } +} + +impl From for Error { + fn from(_self: Void) -> Error { + unreachable!() + } +} diff --git a/rand-core/src/impls.rs b/rand-core/src/impls.rs index d5979be3df9..b8de2f8f9fc 100644 --- a/rand-core/src/impls.rs +++ b/rand-core/src/impls.rs @@ -25,7 +25,7 @@ use core::ptr::copy_nonoverlapping; use core::{fmt, slice}; use core::cmp::min; use core::mem::size_of; -use {RngCore, BlockRngCore, CryptoRng, SeedableRng, Error}; +use {RngCore, BlockRngCore, CryptoRng, SeedableRng}; /// Implement `next_u64` via `next_u32`, little-endian order. pub fn next_u64_via_u32(rng: &mut R) -> u64 { @@ -204,10 +204,13 @@ impl fmt::Debug for BlockRng { impl> RngCore for BlockRng where ::Results: AsRef<[u32]> { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { if self.index >= self.results.as_ref().len() { - self.core.generate(&mut self.results); + self.core.generate(&mut self.results).unwrap_or_else(|err| + panic!("BlockRng: error generating results: {}", err)); self.index = 0; } @@ -237,23 +240,30 @@ where ::Results: AsRef<[u32]> // Read an u64 from the current index read_u64(self.results.as_ref(), index) } else if index >= len { - self.core.generate(&mut self.results); + self.core.generate(&mut self.results).unwrap_or_else(|err| + panic!("BlockRng: error generating results: {}", err)); self.index = 2; read_u64(self.results.as_ref(), 0) } else { let x = self.results.as_ref()[len-1] as u64; - self.core.generate(&mut self.results); + self.core.generate(&mut self.results).unwrap_or_else(|err| + panic!("BlockRng: error generating results: {}", err)); self.index = 1; let y = self.results.as_ref()[0] as u64; (y << 32) | x } } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.try_fill_bytes(dest).unwrap_or_else(|err| + panic!("BlockRng: error generating results: {}", err)); + } // As an optimization we try to write directly into the output buffer. // This is only enabled for little-endian platforms where unaligned writes // are known to be safe and fast. #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - fn fill_bytes(&mut self, dest: &mut [u8]) { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { let mut filled = 0; // Continue filling from the current set of results @@ -274,27 +284,29 @@ where ::Results: AsRef<[u32]> let dest_u32: &mut R::Results = unsafe { ::core::mem::transmute(dest[filled..].as_mut_ptr()) }; - self.core.generate(dest_u32); + self.core.generate(dest_u32)?; filled += self.results.as_ref().len() * 4; } self.index = self.results.as_ref().len(); if len_remainder > 0 { - self.core.generate(&mut self.results); + self.core.generate(&mut self.results)?; let (consumed_u32, _) = fill_via_u32_chunks(&mut self.results.as_ref(), &mut dest[filled..]); self.index = consumed_u32; } + + Ok(()) } #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] - fn fill_bytes(&mut self, dest: &mut [u8]) { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { let mut read_len = 0; while read_len < dest.len() { if self.index >= self.results.as_ref().len() { - self.core.generate(&mut self.results); + self.core.generate(&mut self.results)?; self.index = 0; } let (consumed_u32, filled_u8) = @@ -304,10 +316,8 @@ where ::Results: AsRef<[u32]> self.index += consumed_u32; read_len += filled_u8; } - } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - Ok(self.fill_bytes(dest)) + + Ok(()) } } @@ -323,7 +333,7 @@ impl SeedableRng for BlockRng { } } - fn from_rng(rng: &mut RNG) -> Result { + fn from_rng(rng: &mut RNG) -> Result::Error> { let results_empty = R::Results::default(); Ok(Self { core: R::from_rng(rng)?, diff --git a/rand-core/src/lib.rs b/rand-core/src/lib.rs index e998d1a368a..f19b0426330 100644 --- a/rand-core/src/lib.rs +++ b/rand-core/src/lib.rs @@ -43,10 +43,11 @@ use core::default::Default; use core::convert::AsMut; +use core::fmt::Display; #[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box; -pub use error::{ErrorKind, Error}; +pub use error::{ErrorKind, Error, Void}; mod error; @@ -86,11 +87,13 @@ pub mod le; /// A simple example, obviously not generating very *random* output: /// /// ```rust -/// use rand_core::{RngCore, Error, impls}; +/// use rand_core::{RngCore, Void, impls}; /// /// struct CountingRng(u64); /// /// impl RngCore for CountingRng { +/// type Error = Void; +/// /// fn next_u32(&mut self) -> u32 { /// self.next_u64() as u32 /// } @@ -104,7 +107,7 @@ pub mod le; /// impls::fill_bytes_via_u64(self, dest) /// } /// -/// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { +/// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { /// Ok(self.fill_bytes(dest)) /// } /// } @@ -114,6 +117,10 @@ pub mod le; /// [`Rng`]: https://docs.rs/rand/0.5/rand/trait.Rng.html /// [`impls`]: impls/index.html pub trait RngCore { + /// Error type. May be a void type (i.e. enum with no variants) if no + /// errors are possible. + type Error: Display + Into; + /// Return the next random `u32`. /// /// RNGs must implement at least one method from this trait directly. In @@ -159,7 +166,7 @@ pub trait RngCore { /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling. /// /// [`fill_bytes`]: trait.RngCore.html#method.fill_bytes - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>; + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error>; } /// A trait for RNGs which do not generate random numbers individually, but in @@ -201,15 +208,24 @@ pub trait RngCore { /// type MyRng = BlockRng; /// ``` pub trait BlockRngCore { - /// Results element type, e.g. `u32`. + /// Results element type, e.g. `u32`. [`BlockRng`] must have a + /// corresponding impl of `RngCore` for the item type, which means + /// currently only `u32` is supported. + /// + /// [`BlockRng`]: impls/struct.BlockRng.html 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]> + Default; + + /// Error type. May be a void type (i.e. enum with no variants) if no + /// errors are possible. + type Error: Display + Into; /// Generate a new block of results. - fn generate(&mut self, results: &mut Self::Results); + fn generate(&mut self, results: &mut Self::Results) + -> Result<(), Self::Error>; } /// A marker trait used to indicate that an `RngCore` or `BlockRngCore` @@ -304,7 +320,7 @@ pub trait SeedableRng: Sized { /// [`NewRng`]: https://docs.rs/rand/0.5/rand/trait.NewRng.html /// [`OsRng`]: https://docs.rs/rand/0.5/rand/os/struct.OsRng.html /// [`XorShiftRng`]: https://docs.rs/rand/0.5/rand/prng/xorshift/struct.XorShiftRng.html - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { let mut seed = Self::Seed::default(); rng.try_fill_bytes(seed.as_mut())?; Ok(Self::from_seed(seed)) @@ -313,6 +329,8 @@ pub trait SeedableRng: Sized { impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { (**self).next_u32() @@ -327,13 +345,15 @@ impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R { (**self).fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { (**self).try_fill_bytes(dest) } } #[cfg(any(feature="std", feature="alloc"))] impl RngCore for Box { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { (**self).next_u32() @@ -348,7 +368,7 @@ impl RngCore for Box { (**self).fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { (**self).try_fill_bytes(dest) } } diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index 17e86856c0c..449a80a3f0a 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -173,11 +173,11 @@ impl<'a, T, D: Distribution> Distribution for &'a D { /// With dynamic dispatch (type erasure of `Rng`): /// /// ```rust -/// use rand::{thread_rng, Rng, RngCore}; +/// use rand::{thread_rng, Rng, RngCore, Void}; /// use rand::distributions::Uniform; /// /// let mut rng = thread_rng(); -/// let mut erased_rng: &mut RngCore = &mut rng; +/// let mut erased_rng: &mut RngCore = &mut rng; /// let val: f32 = erased_rng.sample(Uniform); /// println!("f32 from [0,1): {}", val); /// ``` diff --git a/src/distributions/other.rs b/src/distributions/other.rs index 3d797cf6392..e60501e7b91 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -160,12 +160,12 @@ impl Distribution> for Uniform where Uniform: Distribution { #[cfg(test)] mod tests { - use {Rng, RngCore, Uniform}; + use {Rng, RngCore, Uniform, Void}; #[cfg(all(not(feature="std"), feature="alloc"))] use alloc::String; #[test] fn test_misc() { - let mut rng: &mut RngCore = &mut ::test::rng(820); + let mut rng: &mut RngCore = &mut ::test::rng(820); rng.sample::(Uniform); rng.sample::(Uniform); diff --git a/src/entropy_rng.rs b/src/entropy_rng.rs index b6e19d4e4ff..9c8855d477b 100644 --- a/src/entropy_rng.rs +++ b/src/entropy_rng.rs @@ -52,6 +52,8 @@ impl EntropyRng { } impl RngCore for EntropyRng { + type Error = Error; + fn next_u32(&mut self) -> u32 { impls::next_u32_via_fill(self) } diff --git a/src/jitter.rs b/src/jitter.rs index dddde23e79a..91f90dbf0b7 100644 --- a/src/jitter.rs +++ b/src/jitter.rs @@ -752,6 +752,8 @@ fn black_box(dummy: T) -> T { } impl RngCore for JitterRng { + type Error = Error; + fn next_u32(&mut self) -> u32 { // We want to use both parts of the generated entropy if self.data_half_used { diff --git a/src/lib.rs b/src/lib.rs index 79d56dfd61e..92fa13a64b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,7 +271,7 @@ use core::{marker, mem, slice}; // re-exports from rand-core pub use rand_core::{RngCore, CryptoRng, SeedableRng}; -pub use rand_core::{ErrorKind, Error}; +pub use rand_core::{ErrorKind, Error, Void}; // external rngs pub use jitter::JitterRng; @@ -428,7 +428,7 @@ pub trait Rng: RngCore { /// [`try_fill_bytes`]: https://docs.rs/rand-core/0.1/rand-core/trait.RngCore.html#method.try_fill_bytes /// [`fill`]: trait.Rng.html#method.fill /// [`AsByteSliceMut`]: trait.AsByteSliceMut.html - fn try_fill(&mut self, dest: &mut T) -> Result<(), Error> { + fn try_fill(&mut self, dest: &mut T) -> Result<(), Self::Error> { self.try_fill_bytes(dest.as_byte_slice_mut())?; dest.to_le(); Ok(()) @@ -800,6 +800,8 @@ impl NewRng for R { pub struct StdRng(Hc128Rng); impl RngCore for StdRng { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { self.0.next_u32() @@ -814,7 +816,7 @@ impl RngCore for StdRng { self.0.fill_bytes(dest); } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { self.0.try_fill_bytes(dest) } } @@ -826,7 +828,7 @@ impl SeedableRng for StdRng { StdRng(Hc128Rng::from_seed(seed)) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { Hc128Rng::from_rng(rng).map(|rng| StdRng(rng)) } } @@ -875,6 +877,8 @@ impl SeedableRng for StdRng { pub struct SmallRng(XorShiftRng); impl RngCore for SmallRng { + type Error = ::Error; + fn next_u32(&mut self) -> u32 { self.0.next_u32() } @@ -887,7 +891,7 @@ impl RngCore for SmallRng { self.0.fill_bytes(dest); } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { self.0.try_fill_bytes(dest) } } @@ -899,7 +903,7 @@ impl SeedableRng for SmallRng { SmallRng(XorShiftRng::from_seed(seed)) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { XorShiftRng::from_rng(rng).map(|rng| SmallRng(rng)) } } @@ -956,6 +960,7 @@ mod test { pub struct TestRng { inner: R } impl RngCore for TestRng { + type Error = ::Error; fn next_u32(&mut self) -> u32 { self.inner.next_u32() } @@ -965,7 +970,7 @@ mod test { fn fill_bytes(&mut self, dest: &mut [u8]) { self.inner.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { self.inner.try_fill_bytes(dest) } } @@ -1100,7 +1105,7 @@ mod test { fn test_rng_trait_object() { use distributions::{Distribution, Uniform}; let mut rng = rng(109); - let mut r = &mut rng as &mut RngCore; + let mut r = &mut rng as &mut RngCore; r.next_u32(); r.gen::(); let mut v = [1, 1, 1]; @@ -1116,7 +1121,7 @@ mod test { fn test_rng_boxed_trait() { use distributions::{Distribution, Uniform}; let rng = rng(110); - let mut r = Box::new(rng) as Box; + let mut r = Box::new(rng) as Box>; r.next_u32(); r.gen::(); let mut v = [1, 1, 1]; diff --git a/src/mock.rs b/src/mock.rs index 5c73594fa08..5f5f1b91244 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -10,7 +10,7 @@ //! Mock random number generator -use rand_core::{RngCore, Error, impls}; +use rand_core::{RngCore, Void, impls}; /// A simple implementation of `RngCore` for testing purposes. /// @@ -41,6 +41,8 @@ impl StepRng { } impl RngCore for StepRng { + type Error = Void; + fn next_u32(&mut self) -> u32 { self.next_u64() as u32 } @@ -55,7 +57,7 @@ impl RngCore for StepRng { impls::fill_bytes_via_u64(self, dest); } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { Ok(self.fill_bytes(dest)) } } diff --git a/src/os.rs b/src/os.rs index 6d6ae21a15c..6fff73e33aa 100644 --- a/src/os.rs +++ b/src/os.rs @@ -55,6 +55,8 @@ impl OsRng { } impl RngCore for OsRng { + type Error = Error; + fn next_u32(&mut self) -> u32 { impls::next_u32_via_fill(self) } diff --git a/src/prng/chacha.rs b/src/prng/chacha.rs index 30e70d4aa8b..c16c43fcf6c 100644 --- a/src/prng/chacha.rs +++ b/src/prng/chacha.rs @@ -11,7 +11,7 @@ //! The ChaCha random number generator. use core::fmt; -use rand_core::{BlockRngCore, CryptoRng, RngCore, SeedableRng, Error, le}; +use rand_core::{BlockRngCore, CryptoRng, RngCore, SeedableRng, Void, le}; use rand_core::impls::BlockRng; const SEED_WORDS: usize = 8; // 8 words for the 256-bit key @@ -66,6 +66,8 @@ const STATE_WORDS: usize = 16; pub struct ChaChaRng(BlockRng); impl RngCore for ChaChaRng { + type Error = Void; + #[inline] fn next_u32(&mut self) -> u32 { self.0.next_u32() @@ -82,7 +84,7 @@ impl RngCore for ChaChaRng { } #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { self.0.try_fill_bytes(dest) } } @@ -94,7 +96,7 @@ impl SeedableRng for ChaChaRng { ChaChaRng(BlockRng::::from_seed(seed)) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { BlockRng::::from_rng(rng).map(|rng| ChaChaRng(rng)) } } @@ -222,8 +224,9 @@ macro_rules! double_round{ impl BlockRngCore for ChaChaCore { type Item = u32; type Results = [u32; STATE_WORDS]; + type Error = Void; - fn generate(&mut self, results: &mut Self::Results) { + fn generate(&mut self, results: &mut Self::Results) -> Result<(), Void> { // For some reason extracting this part into a separate function // improves performance by 50%. fn core(results: &mut [u32; STATE_WORDS], @@ -243,12 +246,13 @@ impl BlockRngCore for ChaChaCore { // update 128-bit counter self.state[12] = self.state[12].wrapping_add(1); - if self.state[12] != 0 { return; }; + if self.state[12] != 0 { return Ok(()); }; self.state[13] = self.state[13].wrapping_add(1); - if self.state[13] != 0 { return; }; + if self.state[13] != 0 { return Ok(()); }; self.state[14] = self.state[14].wrapping_add(1); - if self.state[14] != 0 { return; }; + if self.state[14] != 0 { return Ok(()); }; self.state[15] = self.state[15].wrapping_add(1); + Ok(()) } } diff --git a/src/prng/hc128.rs b/src/prng/hc128.rs index 61c608ef676..dd8f17a9e2d 100644 --- a/src/prng/hc128.rs +++ b/src/prng/hc128.rs @@ -11,7 +11,7 @@ //! The HC-128 random number generator. use core::fmt; -use rand_core::{BlockRngCore, CryptoRng, RngCore, SeedableRng, Error, le}; +use rand_core::{BlockRngCore, CryptoRng, RngCore, SeedableRng, Void, le}; use rand_core::impls::BlockRng; const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv @@ -65,6 +65,8 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv pub struct Hc128Rng(BlockRng); impl RngCore for Hc128Rng { + type Error = Void; + #[inline(always)] fn next_u32(&mut self) -> u32 { self.0.next_u32() @@ -79,7 +81,7 @@ impl RngCore for Hc128Rng { self.0.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { self.0.try_fill_bytes(dest) } } @@ -91,7 +93,7 @@ impl SeedableRng for Hc128Rng { Hc128Rng(BlockRng::::from_seed(seed)) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { BlockRng::::from_rng(rng).map(|rng| Hc128Rng(rng)) } } @@ -115,8 +117,9 @@ impl fmt::Debug for Hc128Core { impl BlockRngCore for Hc128Core { type Item = u32; type Results = [u32; 16]; + type Error = Void; - fn generate(&mut self, results: &mut Self::Results) { + fn generate(&mut self, results: &mut Self::Results) -> Result<(), Void> { assert!(self.counter1024 % 16 == 0); let cc = self.counter1024 % 512; @@ -161,6 +164,8 @@ impl BlockRngCore for Hc128Core { results[15] = self.step_q(cc+15, dd+0, cc+12, cc+5, cc+3); } self.counter1024 = self.counter1024.wrapping_add(16); + + Ok(()) } } diff --git a/src/prng/isaac.rs b/src/prng/isaac.rs index d8f2e11baa4..d1f43ab1dc6 100644 --- a/src/prng/isaac.rs +++ b/src/prng/isaac.rs @@ -13,7 +13,7 @@ use core::{fmt, slice}; use core::num::Wrapping as w; -use rand_core::{RngCore, SeedableRng, Error, impls, le}; +use rand_core::{RngCore, SeedableRng, Void, impls, le}; #[allow(non_camel_case_types)] type w32 = w; @@ -213,6 +213,8 @@ impl IsaacRng { } impl RngCore for IsaacRng { + type Error = Void; + #[inline] fn next_u32(&mut self) -> u32 { // Using a local variable for `index`, and checking the size avoids a @@ -249,7 +251,7 @@ impl RngCore for IsaacRng { } } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { Ok(self.fill_bytes(dest)) } } @@ -349,7 +351,7 @@ impl SeedableRng for IsaacRng { init(seed_extended, 2) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { // Custom `from_rng` implementation that fills a seed with the same size // as the entire state. let mut seed = [w(0u32); RAND_SIZE]; diff --git a/src/prng/isaac64.rs b/src/prng/isaac64.rs index 27aba17ee70..833672d2e56 100644 --- a/src/prng/isaac64.rs +++ b/src/prng/isaac64.rs @@ -13,7 +13,7 @@ use core::{fmt, slice}; use core::num::Wrapping as w; -use rand_core::{RngCore, SeedableRng, Error, impls, le}; +use rand_core::{RngCore, SeedableRng, Void, impls, le}; #[allow(non_camel_case_types)] type w64 = w; @@ -199,6 +199,8 @@ impl Isaac64Rng { } impl RngCore for Isaac64Rng { + type Error = Void; + #[inline] fn next_u32(&mut self) -> u32 { // Using a local variable for `index`, and checking the size avoids a @@ -253,7 +255,7 @@ impl RngCore for Isaac64Rng { } } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { Ok(self.fill_bytes(dest)) } } @@ -325,7 +327,7 @@ impl SeedableRng for Isaac64Rng { init(seed_extended, 2) } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { // Custom `from_rng` implementation that fills a seed with the same size // as the entire state. let mut seed = [w(0u64); RAND_SIZE]; diff --git a/src/prng/xorshift.rs b/src/prng/xorshift.rs index 87f4d503dd1..439516b75f3 100644 --- a/src/prng/xorshift.rs +++ b/src/prng/xorshift.rs @@ -12,7 +12,7 @@ use core::num::Wrapping as w; use core::{fmt, slice}; -use rand_core::{RngCore, SeedableRng, Error, impls, le}; +use rand_core::{RngCore, SeedableRng, Void, impls, le}; /// An Xorshift[1] random number /// generator. @@ -58,6 +58,8 @@ impl XorShiftRng { } impl RngCore for XorShiftRng { + type Error = Void; + #[inline] fn next_u32(&mut self) -> u32 { let x = self.x; @@ -78,7 +80,7 @@ impl RngCore for XorShiftRng { impls::fill_bytes_via_u32(self, dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Void> { Ok(self.fill_bytes(dest)) } } @@ -105,7 +107,7 @@ impl SeedableRng for XorShiftRng { } } - fn from_rng(rng: &mut R) -> Result { + fn from_rng(rng: &mut R) -> Result::Error> { let mut seed_u32 = [0u32; 4]; loop { unsafe { diff --git a/src/read.rs b/src/read.rs index 231e8376416..a8b134731fc 100644 --- a/src/read.rs +++ b/src/read.rs @@ -46,6 +46,8 @@ impl ReadRng { } impl RngCore for ReadRng { + type Error = Error; + fn next_u32(&mut self) -> u32 { impls::next_u32_via_fill(self) } diff --git a/src/reseeding.rs b/src/reseeding.rs index 7f99f95c573..c26bcf44862 100644 --- a/src/reseeding.rs +++ b/src/reseeding.rs @@ -88,7 +88,7 @@ where R: BlockRngCore + SeedableRng, } /// Reseed the internal PRNG. - pub fn reseed(&mut self) -> Result<(), Error> { + pub fn reseed(&mut self) -> Result<(), ::Error> { self.0.core.reseed() } } @@ -99,6 +99,8 @@ impl RngCore for ReseedingRng where R: BlockRngCore + SeedableRng, ::Results: AsRef<[u32]> { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { self.0.next_u32() @@ -113,7 +115,7 @@ where R: BlockRngCore + SeedableRng, self.0.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { self.0.try_fill_bytes(dest) } } @@ -136,8 +138,9 @@ where R: BlockRngCore + SeedableRng, { type Item = ::Item; type Results = ::Results; + type Error = ::Error; - fn generate(&mut self, results: &mut Self::Results) { + fn generate(&mut self, results: &mut Self::Results) -> Result<(), Self::Error> { if self.bytes_until_reseed <= 0 { // We get better performance by not calling only `auto_reseed` here // and continuing with the rest of the function, but by directly @@ -146,7 +149,7 @@ where R: BlockRngCore + SeedableRng, } let num_bytes = results.as_ref().len() * size_of::(); self.bytes_until_reseed -= num_bytes as i64; - self.inner.generate(results); + self.inner.generate(results) } } @@ -155,7 +158,7 @@ where R: BlockRngCore + SeedableRng, Rsdr: RngCore { /// Reseed the internal PRNG. - fn reseed(&mut self) -> Result<(), Error> { + fn reseed(&mut self) -> Result<(), ::Error> { R::from_rng(&mut self.reseeder).map(|result| { self.bytes_until_reseed = self.threshold; self.inner = result @@ -165,10 +168,12 @@ where R: BlockRngCore + SeedableRng, #[inline(never)] fn reseed_and_generate(&mut self, results: &mut ::Results) + -> Result<(), ::Error> { trace!("Reseeding RNG after {} generated bytes", self.threshold - self.bytes_until_reseed); let threshold = if let Err(e) = self.reseed() { + let e: Error = e.into(); let delay = match e.kind { ErrorKind::Transient => 0, kind @ _ if kind.should_retry() => self.threshold >> 8, @@ -183,7 +188,7 @@ where R: BlockRngCore + SeedableRng, let num_bytes = results.as_ref().len() * size_of::<::Item>(); self.bytes_until_reseed = threshold - num_bytes as i64; - self.inner.generate(results); + self.inner.generate(results) } } diff --git a/src/thread_rng.rs b/src/thread_rng.rs index 9217d7b8851..8309d20d1a7 100644 --- a/src/thread_rng.rs +++ b/src/thread_rng.rs @@ -13,9 +13,10 @@ use std::cell::RefCell; use std::rc::Rc; -use {RngCore, CryptoRng, SeedableRng, EntropyRng}; +use rand_core::{RngCore, BlockRngCore, CryptoRng, SeedableRng}; +use EntropyRng; use prng::hc128::Hc128Core; -use {Distribution, Uniform, Rng, Error}; +use {Distribution, Uniform, Rng}; use reseeding::ReseedingRng; // Number of generated bytes after which to reseed `TreadRng`. @@ -78,6 +79,8 @@ pub fn thread_rng() -> ThreadRng { } impl RngCore for ThreadRng { + type Error = ::Error; + #[inline(always)] fn next_u32(&mut self) -> u32 { self.rng.borrow_mut().next_u32() @@ -92,7 +95,7 @@ impl RngCore for ThreadRng { self.rng.borrow_mut().fill_bytes(bytes) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> { self.rng.borrow_mut().try_fill_bytes(dest) } }