From 908fda4206e9fc9f7cbd320acfdab274a0f3fb3d Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Thu, 9 Nov 2017 12:01:07 +0000 Subject: [PATCH] Fix: Error::new(_, _, None) was not usable Type deduction failed due to lack of bounds on E. --- rand_core/src/lib.rs | 19 ++++++++++++++----- src/os.rs | 45 +++++++++++++++++++++++++------------------- src/read.rs | 5 +++-- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index c1cdfc74c78..d5a9ab0b321 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -298,7 +298,16 @@ pub struct Error { } impl Error { - /// Create a new instance, with specified kind, message, and optionally a + /// Create a new instance, with specified kind and a message. + pub fn new(kind: ErrorKind, msg: &'static str) -> Self { + #[cfg(feature="std")] { + Self { kind, msg, cause: None } + } + #[cfg(not(feature="std"))] { + Self { kind, msg } + } + } + /// Create a new instance, with specified kind, message, and a /// chained cause. /// /// Note: `stdError` is an alias for `std::error::Error`. @@ -308,17 +317,17 @@ impl Error { /// type `E` (because both `Box` and `stdError` are unavailable), and the /// `cause` is ignored. #[cfg(feature="std")] - pub fn new(kind: ErrorKind, msg: &'static str, cause: Option) -> Self + pub fn new_with_cause(kind: ErrorKind, msg: &'static str, cause: E) -> Self where E: Into> { - Self { kind, msg, cause: cause.map(|inner| inner.into()) } + Self { kind, msg, cause: Some(cause.into()) } } - /// Create a new instance, with specified kind, message, and optionally a + /// Create a new instance, with specified kind, message, and a /// chained cause. /// /// In `no_std` mode the *cause* is ignored. #[cfg(not(feature="std"))] - pub fn new(kind: ErrorKind, msg: &'static str, _cause: Option) -> Self { + pub fn new_with_cause(kind: ErrorKind, msg: &'static str, _cause: E) -> Self { Self { kind, msg } } diff --git a/src/os.rs b/src/os.rs index 2649764de71..e65d770af1e 100644 --- a/src/os.rs +++ b/src/os.rs @@ -84,8 +84,9 @@ impl ReadRng { fn try_fill(&mut self, mut dest: &mut [u8]) -> Result<(), Error> { if dest.len() == 0 { return Ok(()); } // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`. - self.0.read_exact(dest).map_err(|err| - Error::new(ErrorKind::Unavailable, "error reading random device", Some(err))) + self.0.read_exact(dest).map_err(|err| { + Error::new_with_cause(ErrorKind::Unavailable, "error reading random device", err) + }) } } @@ -148,9 +149,13 @@ mod imp { if result == -1 { let err = io::Error::last_os_error(); if err.kind() == io::ErrorKind::Interrupted { - continue + continue; } else { - return Err(Error::new(ErrorKind::Other, "unexpected getrandom error", Some(err))); + return Err(Error::new_with_cause( + ErrorKind::Other, + "unexpected getrandom error", + err, + )); } } else { read += result as usize; @@ -212,8 +217,9 @@ mod imp { return Ok(OsRng { inner: OsGetrandomRng }); } - let reader = File::open("/dev/urandom").map_err(|err| - Error::new(ErrorKind::Unavailable, "error opening random device", Some(err)))?; + let reader = File::open("/dev/urandom").map_err(|err| { + Error::new_with_cause(ErrorKind::Unavailable, "error opening random device", err) + })?; let reader_rng = ReadRng(reader); Ok(OsRng { inner: OsReadRng(reader_rng) }) @@ -260,10 +266,10 @@ mod imp { SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr()) }; if ret == -1 { - Err(Error::new( + Err(Error::new_with_cause( ErrorKind::Unavailable, "couldn't generate random bytes", - Some(io::Error::last_os_error()))) + io::Error::last_os_error())) } else { Ok(()) } @@ -297,11 +303,11 @@ mod imp { ptr::null(), 0) }; if ret == -1 || s_len != s.len() { - // Old format string: "kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})" + // Old format string: + // "kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})" return Err(Error::new( ErrorKind::Unavailable, - "kern.arandom sysctl failed", - None)); + "kern.arandom sysctl failed")); } } Ok(()) @@ -331,10 +337,10 @@ mod imp { libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len()) }; if ret == -1 { - return Err(Error::new( + return Err(Error::new_with_cause( ErrorKind::Unavailable, "getentropy failed", - Some(io::Error::last_os_error()))); + io::Error::last_os_error())); } } Ok(()) @@ -357,8 +363,9 @@ mod imp { impl OsRng { pub fn new() -> Result { - let reader = File::open("rand:").map_err(|err| - Error::new(ErrorKind::Unavailable, "error opening random device", Some(err)))?; + let reader = File::open("rand:").map_err(|err| { + Error::new_with_cause(ErrorKind::Unavailable, "error opening random device", err) + })?; let reader_rng = ReadRng(reader); Ok(OsRng { inner: reader_rng }) @@ -391,10 +398,10 @@ mod imp { match fuchsia_zircon::cprng_draw(&mut s[filled..]) { Ok(actual) => filled += actual, Err(e) => { - return Err(Error::new( + return Err(Error::new_with_cause( ErrorKind::Unavailable, "cprng_draw failed", - Some(e))); + e)); } }; } @@ -434,10 +441,10 @@ mod imp { SystemFunction036(slice.as_mut_ptr(), slice.len() as ULONG) }; if ret == 0 { - return Err(Error::new( + return Err(Error::new_with_cause( ErrorKind::Unavailable, "couldn't generate random bytes", - Some(io::Error::last_os_error()))); + io::Error::last_os_error())); } } Ok(()) diff --git a/src/read.rs b/src/read.rs index 64fb1485620..acc905b7010 100644 --- a/src/read.rs +++ b/src/read.rs @@ -68,8 +68,9 @@ impl Rng for ReadRng { fn try_fill(&mut self, dest: &mut [u8]) -> Result<(), Error> { if dest.len() == 0 { return Ok(()); } // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`. - self.reader.read_exact(dest).map_err(|err| - Error::new(ErrorKind::Unavailable, "ReadRng: read error", Some(err))) + self.reader.read_exact(dest).map_err(|err| { + Error::new_with_cause(ErrorKind::Unavailable, "ReadRng: read error", err) + }) } }