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

std: expose const_io_error! as const_error! #133449

Merged
merged 2 commits into from
Nov 27, 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
2 changes: 1 addition & 1 deletion library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3020,7 +3020,7 @@ impl DirBuilder {
match path.parent() {
Some(p) => self.create_dir_all(p)?,
None => {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::Uncategorized,
"failed to create whole tree",
));
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/io/buffered/bufreader/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Buffer {
match Box::try_new_uninit_slice(capacity) {
Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }),
Err(_) => {
Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer"))
Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer"))
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/buffered/bufwriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<W: Write> BufWriter<W> {

pub(crate) fn try_new_buffer() -> io::Result<Vec<u8>> {
Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| {
io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer")
io::const_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer")
})
}

Expand Down Expand Up @@ -238,7 +238,7 @@ impl<W: ?Sized + Write> BufWriter<W> {

match r {
Ok(0) => {
return Err(io::const_io_error!(
return Err(io::const_error!(
ErrorKind::WriteZero,
"failed to write the buffered data",
));
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ where
self.pos = n;
Ok(self.pos)
}
None => Err(io::const_io_error!(
None => Err(io::const_error!(
ErrorKind::InvalidInput,
"invalid seek to a negative or overflowing position",
)),
Expand Down Expand Up @@ -446,7 +446,7 @@ fn reserve_and_pad<A: Allocator>(
buf_len: usize,
) -> io::Result<usize> {
let pos: usize = (*pos_mut).try_into().map_err(|_| {
io::const_io_error!(
io::const_error!(
ErrorKind::InvalidInput,
"cursor position exceeds maximum possible vector length",
)
Expand Down
67 changes: 40 additions & 27 deletions library/std/src/io/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,31 @@ impl fmt::Debug for Error {
#[allow(dead_code)]
impl Error {
pub(crate) const INVALID_UTF8: Self =
const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");

pub(crate) const READ_EXACT_EOF: Self =
const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");

pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_io_error!(
pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!(
ErrorKind::NotFound,
"The number of hardware threads is not known for the target platform"
);

pub(crate) const UNSUPPORTED_PLATFORM: Self =
const_io_error!(ErrorKind::Unsupported, "operation not supported on this platform");
const_error!(ErrorKind::Unsupported, "operation not supported on this platform");

pub(crate) const WRITE_ALL_EOF: Self =
const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer");
const_error!(ErrorKind::WriteZero, "failed to write whole buffer");

pub(crate) const ZERO_TIMEOUT: Self =
const_io_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<alloc::ffi::NulError> for Error {
/// Converts a [`alloc::ffi::NulError`] into a [`Error`].
fn from(_: alloc::ffi::NulError) -> Error {
const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
const_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -592,13 +603,15 @@ impl Error {
///
/// This function does not allocate.
///
/// You should not use this directly, and instead use the `const_io_error!`
/// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
/// You should not use this directly, and instead use the `const_error!`
/// macro: `io::const_error!(ErrorKind::Something, "some_message")`.
///
/// This function should maybe change to `from_static_message<const MSG: &'static
/// str>(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) }
}

Expand Down
10 changes: 5 additions & 5 deletions library/std/src/io/error/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_io_error};
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
use crate::assert_matches::assert_matches;
use crate::mem::size_of;
use crate::sys::decode_error_kind;
Expand Down Expand Up @@ -60,7 +60,7 @@ fn test_downcasting() {

#[test]
fn test_const() {
const E: Error = const_io_error!(ErrorKind::NotFound, "hello");
const E: Error = const_error!(ErrorKind::NotFound, "hello");

assert_eq!(E.kind(), ErrorKind::NotFound);
assert_eq!(E.to_string(), "hello");
Expand Down Expand Up @@ -110,13 +110,13 @@ fn test_simple_message_packing() {
}};
}

let not_static = const_io_error!(Uncategorized, "not a constant!");
let not_static = const_error!(Uncategorized, "not a constant!");
check_simple_msg!(not_static, Uncategorized, "not a constant!");

const CONST: Error = const_io_error!(NotFound, "definitely a constant!");
const CONST: Error = const_error!(NotFound, "definitely a constant!");
check_simple_msg!(CONST, NotFound, "definitely a constant!");

static STATIC: Error = const_io_error!(BrokenPipe, "a constant, sort of!");
static STATIC: Error = const_error!(BrokenPipe, "a constant, sort of!");
check_simple_msg!(STATIC, BrokenPipe, "a constant, sort of!");
}

Expand Down
7 changes: 5 additions & 2 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,12 @@ fn take_eof() {

impl Read for R {
fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
Err(io::const_io_error!(io::ErrorKind::Other, ""))
Err(io::const_error!(io::ErrorKind::Other, ""))
}
}
impl BufRead for R {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Err(io::const_io_error!(io::ErrorKind::Other, ""))
Err(io::const_error!(io::ErrorKind::Other, ""))
}
fn consume(&mut self, _amt: usize) {}
}
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -410,6 +411,7 @@
// Only for const-ness:
// tidy-alphabetical-start
#![feature(const_collections_with_hasher)]
#![feature(io_const_error)]
#![feature(thread_local_internals)]
// tidy-alphabetical-end
//
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ where
}
}
Err(last_err.unwrap_or_else(|| {
io::const_io_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
}))
}
4 changes: 1 addition & 3 deletions library/std/src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,7 @@ impl UdpSocket {
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
match addr.to_socket_addrs()?.next() {
Some(addr) => self.0.send_to(buf, &addr),
None => {
Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to"))
}
None => Err(io::const_error!(ErrorKind::InvalidInput, "no addresses to send data to")),
}
}

Expand Down
8 changes: 4 additions & 4 deletions library/std/src/os/unix/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s
let bytes = path.as_os_str().as_bytes();

if bytes.contains(&0) {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::InvalidInput,
"paths must not contain interior null bytes",
));
}

if bytes.len() >= addr.sun_path.len() {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::InvalidInput,
"path must be shorter than SUN_LEN",
));
Expand Down Expand Up @@ -119,7 +119,7 @@ impl SocketAddr {
// linux returns zero bytes of address
len = SUN_PATH_OFFSET as libc::socklen_t; // i.e., zero-length address
} else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::InvalidInput,
"file descriptor did not correspond to a Unix socket",
));
Expand Down Expand Up @@ -273,7 +273,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr {
addr.sun_family = libc::AF_UNIX as libc::sa_family_t;

if name.len() + 1 > addr.sun_path.len() {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::InvalidInput,
"abstract socket name must be shorter than SUN_LEN",
));
Expand Down
5 changes: 2 additions & 3 deletions library/std/src/os/wasi/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl FileExt for fs::File {
a if a == wasi::ADVICE_DONTNEED.raw() => wasi::ADVICE_DONTNEED,
a if a == wasi::ADVICE_NOREUSE.raw() => wasi::ADVICE_NOREUSE,
_ => {
return Err(io::const_io_error!(
return Err(io::const_error!(
io::ErrorKind::InvalidInput,
"invalid parameter 'advice'",
));
Expand Down Expand Up @@ -560,6 +560,5 @@ pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) ->
}

fn osstr2str(f: &OsStr) -> io::Result<&str> {
f.to_str()
.ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8"))
}
2 changes: 1 addition & 1 deletion library/std/src/os/windows/io/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl OwnedSocket {

#[cfg(target_vendor = "uwp")]
pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
Err(io::const_error!(io::ErrorKind::Unsupported, "Unavailable on UWP"))
}
}

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3580,7 +3580,7 @@ impl Error for StripPrefixError {
pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
let path = path.as_ref();
if path.as_os_str().is_empty() {
Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",))
} else {
sys::path::absolute(path)
}
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/common/small_c_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const MAX_STACK_ALLOCATION: usize = 384;
const MAX_STACK_ALLOCATION: usize = 32;

const NUL_ERR: io::Error =
io::const_io_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte");
io::const_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte");

#[inline]
pub fn run_path_with_cstr<T>(path: &Path, f: &dyn Fn(&CStr) -> io::Result<T>) -> io::Result<T> {
Expand Down
16 changes: 7 additions & 9 deletions library/std/src/sys/pal/hermit/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ impl OpenOptions {
(false, _, true) => Ok(O_WRONLY | O_APPEND),
(true, _, true) => Ok(O_RDWR | O_APPEND),
(false, false, false) => {
Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid access mode"))
Err(io::const_error!(ErrorKind::InvalidInput, "invalid access mode"))
}
}
}
Expand All @@ -304,18 +304,16 @@ impl OpenOptions {
(true, false) => {}
(false, false) => {
if self.truncate || self.create || self.create_new {
return Err(io::const_io_error!(
ErrorKind::InvalidInput,
"invalid creation mode",
));
return Err(
io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
);
}
}
(_, true) => {
if self.truncate && !self.create_new {
return Err(io::const_io_error!(
ErrorKind::InvalidInput,
"invalid creation mode",
));
return Err(
io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",),
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/hermit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn unsupported<T>() -> crate::io::Result<T> {
}

pub fn unsupported_err() -> crate::io::Error {
crate::io::const_io_error!(
crate::io::const_error!(
crate::io::ErrorKind::Unsupported,
"operation not supported on HermitCore yet",
)
Expand Down
Loading
Loading