Skip to content

Commit

Permalink
Fix: Error::new(_, _, None) was not usable
Browse files Browse the repository at this point in the history
Type deduction failed due to lack of bounds on E.
  • Loading branch information
dhardy committed Nov 9, 2017
1 parent bd60937 commit 908fda4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
19 changes: 14 additions & 5 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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<E>(kind: ErrorKind, msg: &'static str, cause: Option<E>) -> Self
pub fn new_with_cause<E>(kind: ErrorKind, msg: &'static str, cause: E) -> Self
where E: Into<Box<stdError + Send + Sync>>
{
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<E>(kind: ErrorKind, msg: &'static str, _cause: Option<E>) -> Self {
pub fn new_with_cause<E>(kind: ErrorKind, msg: &'static str, _cause: E) -> Self {
Self { kind, msg }
}

Expand Down
45 changes: 26 additions & 19 deletions src/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ impl<R: Read> ReadRng<R> {
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)
})
}
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) })
Expand Down Expand Up @@ -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(())
}
Expand Down Expand Up @@ -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(())
Expand Down Expand Up @@ -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(())
Expand All @@ -357,8 +363,9 @@ mod imp {

impl OsRng {
pub fn new() -> Result<OsRng, Error> {
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 })
Expand Down Expand Up @@ -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));
}
};
}
Expand Down Expand Up @@ -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(())
Expand Down
5 changes: 3 additions & 2 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ impl<R: Read> Rng for ReadRng<R> {
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)
})
}
}

Expand Down

0 comments on commit 908fda4

Please sign in to comment.