diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 5d7adcace5247..d98ab35a8809e 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -151,27 +151,38 @@ pub type RawOsError = sys::RawOsError; // (For the sake of being explicit: the alignment requirement here only matters // if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't // matter at all) +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] #[repr(align(4))] #[derive(Debug)] -pub(crate) struct SimpleMessage { - kind: ErrorKind, - message: &'static str, -} - -impl SimpleMessage { - pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self { - Self { kind, message } - } +pub struct SimpleMessage { + pub kind: ErrorKind, + pub message: &'static str, } -/// Creates and returns an `io::Error` for a given `ErrorKind` and constant -/// message. This doesn't allocate. -pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) { - $crate::io::error::Error::from_static_message({ - const MESSAGE_DATA: $crate::io::error::SimpleMessage = - $crate::io::error::SimpleMessage::new($kind, $message); - &MESSAGE_DATA - }) +/// Creates a new I/O error from a known kind of error and a string literal. +/// +/// Contrary to [`Error::new`], this macro does not allocate and can be used in +/// `const` contexts. +/// +/// # Example +/// ``` +/// #![feature(io_const_error)] +/// use std::io::{const_error, Error, ErrorKind}; +/// +/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works"); +/// +/// fn not_here() -> Result<(), Error> { +/// Err(FAIL) +/// } +/// ``` +#[rustc_macro_transparency = "semitransparent"] +#[unstable(feature = "io_const_error", issue = "133448")] +#[allow_internal_unstable(hint_must_use, io_const_error_internals)] +pub macro const_error($kind:expr, $message:expr $(,)?) { + $crate::hint::must_use($crate::io::Error::from_static_message( + const { &$crate::io::SimpleMessage { kind: $kind, message: $message } }, + )) } // As with `SimpleMessage`: `#[repr(align(4))]` here is just because @@ -598,7 +609,9 @@ impl Error { /// This function should maybe change to `from_static_message(kind: ErrorKind)` in the future, when const generics allow that. #[inline] - pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error { + #[doc(hidden)] + #[unstable(feature = "io_const_error_internals", issue = "none")] + pub const fn from_static_message(msg: &'static SimpleMessage) -> Error { Self { repr: Repr::new_simple_message(msg) } } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 21e7077495450..4ffb04630061f 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -301,12 +301,15 @@ mod tests; pub use core::io::{BorrowedBuf, BorrowedCursor}; use core::slice::memchr; -pub(crate) use error::const_io_error; - #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] pub use self::buffered::WriterPanicked; #[unstable(feature = "raw_os_error_ty", issue = "107792")] pub use self::error::RawOsError; +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] +pub use self::error::SimpleMessage; +#[unstable(feature = "io_const_error", issue = "133448")] +pub use self::error::const_error; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; pub(crate) use self::stdio::attempt_print_to_stderr; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ee6fceb024fd7..f1eeac3354009 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -340,6 +340,7 @@ #![feature(fmt_internals)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(hint_must_use)] #![feature(ip)] #![feature(lazy_get)] #![feature(maybe_uninit_slice)]