Rollup merge of #149521 - a1phyr:improve_io_error, r=joboet

Improve `io::Error::downcast`

Rewrite this function to help to compiler understand what is going on here.
This commit is contained in:
Matthias Krüger 2025-12-04 09:22:10 +01:00 committed by GitHub
commit 170fffd31d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 12 additions and 24 deletions

View file

@ -950,19 +950,19 @@ impl Error {
where
E: error::Error + Send + Sync + 'static,
{
match self.repr.into_data() {
ErrorData::Custom(b) if b.error.is::<E>() => {
let res = (*b).error.downcast::<E>();
// downcast is a really trivial and is marked as inline, so
// it's likely be inlined here.
//
// And the compiler should be able to eliminate the branch
// that produces `Err` here since b.error.is::<E>()
// returns true.
Ok(*res.unwrap())
if let ErrorData::Custom(c) = self.repr.data()
&& c.error.is::<E>()
{
if let ErrorData::Custom(b) = self.repr.into_data()
&& let Ok(err) = b.error.downcast::<E>()
{
Ok(*err)
} else {
// Safety: We have just checked that the condition is true
unsafe { crate::hint::unreachable_unchecked() }
}
repr_data => Err(Self { repr: Repr::new(repr_data) }),
} else {
Err(self)
}
}

View file

@ -133,15 +133,6 @@ unsafe impl Send for Repr {}
unsafe impl Sync for Repr {}
impl Repr {
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
match dat {
ErrorData::Os(code) => Self::new_os(code),
ErrorData::Simple(kind) => Self::new_simple(kind),
ErrorData::SimpleMessage(simple_message) => Self::new_simple_message(simple_message),
ErrorData::Custom(b) => Self::new_custom(b),
}
}
pub(super) fn new_custom(b: Box<Custom>) -> Self {
let p = Box::into_raw(b).cast::<u8>();
// Should only be possible if an allocator handed out a pointer with

View file

@ -10,9 +10,6 @@ pub(super) struct Repr(Inner);
impl Repr {
#[inline]
pub(super) fn new(dat: ErrorData<Box<Custom>>) -> Self {
Self(dat)
}
pub(super) fn new_custom(b: Box<Custom>) -> Self {
Self(Inner::Custom(b))
}