From baa2cf5ea610d10be1e3cb13f7da4f2d752aa69a Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Fri, 19 Jan 2024 09:26:56 +1100 Subject: [PATCH] Update `std::io::Error::downcast` return type and update its doc according to decision made by rust libs-api team. Signed-off-by: Jiahao XU --- library/std/src/io/error.rs | 36 ++++++++++++++++++++++++++----- library/std/src/io/error/tests.rs | 4 ++-- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index b63091deac27e..13cc0511e103e 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -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 @@ -852,13 +852,39 @@ impl Error { /// impl From for E { /// fn from(err: io::Error) -> E { /// err.downcast::() - /// .map(|b| *b) /// .unwrap_or_else(E::Io) /// } /// } + /// + /// impl From 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(self) -> result::Result, Self> + pub fn downcast(self) -> result::Result where E: error::Error + Send + Sync + 'static, { @@ -872,7 +898,7 @@ impl Error { // And the compiler should be able to eliminate the branch // that produces `Err` here since b.error.is::() // returns true. - Ok(res.unwrap()) + Ok(*res.unwrap()) } repr_data => Err(Self { repr: Repr::new(repr_data) }), } diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index 36d52aef03cb7..fc6db2825e811 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -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 = io_error.downcast().unwrap(); + let e: Bojji = io_error.downcast().unwrap(); assert!(e.0); // Case 2: custom error, downcast fails @@ -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 = io_error.downcast().unwrap(); + let e: Bojji = io_error.downcast().unwrap(); assert!(e.0); // Case 3: os error