Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update std::io::Error::downcast return type #120117

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,12 +816,12 @@ impl Error {
}
}

/// Attempt to downgrade the inner error to `E` if any.
/// Attempt to downcast the inner error to `E` if any.
///
/// If this [`Error`] was constructed via [`new`] then this function will
/// attempt to perform downgrade on it, otherwise it will return [`Err`].
///
/// If downgrade succeeds, it will return [`Ok`], otherwise it will also
/// If the downcast succeeds, it will return [`Ok`], otherwise it will also
/// return [`Err`].
///
/// [`new`]: Error::new
Expand Down Expand Up @@ -852,13 +852,39 @@ impl Error {
/// impl From<io::Error> for E {
/// fn from(err: io::Error) -> E {
/// err.downcast::<E>()
/// .map(|b| *b)
/// .unwrap_or_else(E::Io)
/// }
/// }
///
/// impl From<E> for io::Error {
/// fn from(err: E) -> io::Error {
/// match err {
/// E::Io(io_error) => io_error,
/// e => io::Error::new(io::ErrorKind::Other, e),
/// }
/// }
/// }
///
/// # fn main() {
/// let e = E::SomeOtherVariant;
/// // Convert it to an io::Error
/// let io_error = io::Error::from(e);
/// // Cast it back to the original variant
/// let e = E::from(io_error);
/// assert!(matches!(e, E::SomeOtherVariant));
///
/// let io_error = io::Error::from(io::ErrorKind::AlreadyExists);
/// // Convert it to E
/// let e = E::from(io_error);
/// // Cast it back to the original variant
/// let io_error = io::Error::from(e);
/// assert_eq!(io_error.kind(), io::ErrorKind::AlreadyExists);
/// assert!(io_error.get_ref().is_none());
/// assert!(io_error.raw_os_error().is_none());
/// # }
/// ```
#[unstable(feature = "io_error_downcast", issue = "99262")]
pub fn downcast<E>(self) -> result::Result<Box<E>, Self>
pub fn downcast<E>(self) -> result::Result<E, Self>
where
E: error::Error + Send + Sync + 'static,
{
Expand All @@ -872,7 +898,7 @@ impl Error {
// And the compiler should be able to eliminate the branch
// that produces `Err` here since b.error.is::<E>()
// returns true.
Ok(res.unwrap())
Ok(*res.unwrap())
}
repr_data => Err(Self { repr: Repr::new(repr_data) }),
}
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/error/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl error::Error for E {}
fn test_std_io_error_downcast() {
// Case 1: custom error, downcast succeeds
let io_error = Error::new(ErrorKind::Other, Bojji(true));
let e: Box<Bojji> = io_error.downcast().unwrap();
let e: Bojji = io_error.downcast().unwrap();
assert!(e.0);

// Case 2: custom error, downcast fails
Expand All @@ -166,7 +166,7 @@ fn test_std_io_error_downcast() {

// ensures that the custom error is intact
assert_eq!(ErrorKind::Other, io_error.kind());
let e: Box<Bojji> = io_error.downcast().unwrap();
let e: Bojji = io_error.downcast().unwrap();
assert!(e.0);

// Case 3: os error
Expand Down
Loading