Adjust usage of std::io::ErrorKind to be core compatible

* Checking exhaustion will no longer be possible for `repr_bitpacked`. Moving `kind_from_prim` into an associated function, and setting it up to be moved into `core::io` as well.
* `ErrorKind::as_str` is private, but it's only usage is trivially replaced with `Display::fmt`
* The features io_error_inprogress, io_error_more, and io_error_uncategorized will all need to be enabled
This commit is contained in:
Zac Harrold
2026-04-01 15:45:35 +11:00
parent 08bd077df4
commit 6960e7c958
4 changed files with 74 additions and 63 deletions
+1 -1
View File
@@ -1038,7 +1038,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{detail} (os error {code})")
}
ErrorData::Custom(ref c) => c.error.fmt(fmt),
ErrorData::Simple(kind) => write!(fmt, "{}", kind.as_str()),
ErrorData::Simple(kind) => kind.fmt(fmt),
ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
}
}
+69 -61
View File
@@ -253,7 +253,7 @@ unsafe fn decode_repr<C, F>(ptr: NonNull<()>, make_custom: F) -> ErrorData<C>
}
TAG_SIMPLE => {
let kind_bits = (bits >> 32) as u32;
let kind = kind_from_prim(kind_bits).unwrap_or_else(|| {
let kind = ErrorKind::from_prim(kind_bits).unwrap_or_else(|| {
debug_assert!(false, "Invalid io::error::Repr bits: `Repr({:#018x})`", bits);
// This means the `ptr` passed in was not valid, which violates
// the unsafe contract of `decode_repr`.
@@ -283,67 +283,75 @@ unsafe fn decode_repr<C, F>(ptr: NonNull<()>, make_custom: F) -> ErrorData<C>
}
}
// This compiles to the same code as the check+transmute, but doesn't require
// unsafe, or to hard-code max ErrorKind or its size in a way the compiler
// couldn't verify.
#[inline]
fn kind_from_prim(ek: u32) -> Option<ErrorKind> {
macro_rules! from_prim {
($prim:expr => $Enum:ident { $($Variant:ident),* $(,)? }) => {{
// Force a compile error if the list gets out of date.
const _: fn(e: $Enum) = |e: $Enum| match e {
$($Enum::$Variant => ()),*
};
match $prim {
$(v if v == ($Enum::$Variant as _) => Some($Enum::$Variant),)*
_ => None,
}
}}
impl ErrorKind {
// This compiles to the same code as the check+transmute, but doesn't require
// unsafe, or to hard-code max ErrorKind or its size in a way the compiler
// couldn't verify.
#[inline]
#[unstable(
feature = "core_io_internals",
reason = "exposed only for libstd",
issue = "none"
)]
#[doc(hidden)]
pub const fn from_prim(ek: u32) -> Option<Self> {
macro_rules! from_prim {
($prim:expr => $Enum:ident { $($Variant:ident),* $(,)? }) => {{
// Force a compile error if the list gets out of date.
const _: fn(e: $Enum) = |e: $Enum| match e {
$($Enum::$Variant => (),)*
};
match $prim {
$(v if v == ($Enum::$Variant as _) => Some($Enum::$Variant),)*
_ => None,
}
}}
}
from_prim!(ek => ErrorKind {
NotFound,
PermissionDenied,
ConnectionRefused,
ConnectionReset,
HostUnreachable,
NetworkUnreachable,
ConnectionAborted,
NotConnected,
AddrInUse,
AddrNotAvailable,
NetworkDown,
BrokenPipe,
AlreadyExists,
WouldBlock,
NotADirectory,
IsADirectory,
DirectoryNotEmpty,
ReadOnlyFilesystem,
FilesystemLoop,
StaleNetworkFileHandle,
InvalidInput,
InvalidData,
TimedOut,
WriteZero,
StorageFull,
NotSeekable,
QuotaExceeded,
FileTooLarge,
ResourceBusy,
ExecutableFileBusy,
Deadlock,
CrossesDevices,
TooManyLinks,
InvalidFilename,
ArgumentListTooLong,
Interrupted,
Other,
UnexpectedEof,
Unsupported,
OutOfMemory,
InProgress,
Uncategorized,
})
}
from_prim!(ek => ErrorKind {
NotFound,
PermissionDenied,
ConnectionRefused,
ConnectionReset,
HostUnreachable,
NetworkUnreachable,
ConnectionAborted,
NotConnected,
AddrInUse,
AddrNotAvailable,
NetworkDown,
BrokenPipe,
AlreadyExists,
WouldBlock,
NotADirectory,
IsADirectory,
DirectoryNotEmpty,
ReadOnlyFilesystem,
FilesystemLoop,
StaleNetworkFileHandle,
InvalidInput,
InvalidData,
TimedOut,
WriteZero,
StorageFull,
NotSeekable,
QuotaExceeded,
FileTooLarge,
ResourceBusy,
ExecutableFileBusy,
Deadlock,
CrossesDevices,
TooManyLinks,
InvalidFilename,
ArgumentListTooLong,
Interrupted,
Other,
UnexpectedEof,
Unsupported,
OutOfMemory,
InProgress,
Uncategorized,
})
}
// Some static checking to alert us if a change breaks any of the assumptions
+3
View File
@@ -344,6 +344,9 @@
#![feature(hashmap_internals)]
#![feature(hint_must_use)]
#![feature(int_from_ascii)]
#![feature(io_error_inprogress)]
#![feature(io_error_more)]
#![feature(io_error_uncategorized)]
#![feature(ip)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
+1 -1
View File
@@ -60,6 +60,6 @@ pub fn error_string(errno: i32) -> String {
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
format!("user-specified error {errno:08x}")
} else {
decode_error_kind(errno).as_str().into()
format!("{}", decode_error_kind(errno))
}
}