Skip to content

Commit 554918e

Browse files
committed
Hide Repr details from io::Error, and rework io::Error::new_const.
1 parent 71226d7 commit 554918e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+345
-269
lines changed

library/std/src/ffi/c_str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ impl fmt::Display for NulError {
10771077
impl From<NulError> for io::Error {
10781078
/// Converts a [`NulError`] into a [`io::Error`].
10791079
fn from(_: NulError) -> io::Error {
1080-
io::Error::new_const(io::ErrorKind::InvalidInput, &"data provided contains a nul byte")
1080+
io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
10811081
}
10821082
}
10831083

library/std/src/fs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,9 +2263,9 @@ impl DirBuilder {
22632263
match path.parent() {
22642264
Some(p) => self.create_dir_all(p)?,
22652265
None => {
2266-
return Err(io::Error::new_const(
2266+
return Err(io::const_io_error!(
22672267
io::ErrorKind::Uncategorized,
2268-
&"failed to create whole tree",
2268+
"failed to create whole tree",
22692269
));
22702270
}
22712271
}

library/std/src/io/buffered/bufreader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ impl<R: Read> Read for BufReader<R> {
357357
let mut bytes = Vec::new();
358358
self.read_to_end(&mut bytes)?;
359359
let string = crate::str::from_utf8(&bytes).map_err(|_| {
360-
io::Error::new_const(
360+
io::const_io_error!(
361361
io::ErrorKind::InvalidData,
362-
&"stream did not contain valid UTF-8",
362+
"stream did not contain valid UTF-8",
363363
)
364364
})?;
365365
*buf += string;

library/std/src/io/buffered/bufwriter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::error;
22
use crate::fmt;
33
use crate::io::{
4-
self, Error, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
4+
self, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
55
};
66
use crate::mem;
77
use crate::ptr;
@@ -168,9 +168,9 @@ impl<W: Write> BufWriter<W> {
168168

169169
match r {
170170
Ok(0) => {
171-
return Err(Error::new_const(
171+
return Err(io::const_io_error!(
172172
ErrorKind::WriteZero,
173-
&"failed to write the buffered data",
173+
"failed to write the buffered data",
174174
));
175175
}
176176
Ok(n) => guard.consume(n),

library/std/src/io/cursor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod tests;
44
use crate::io::prelude::*;
55

66
use crate::cmp;
7-
use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
7+
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
88

99
use core::convert::TryInto;
1010

@@ -297,9 +297,9 @@ where
297297
self.pos = n;
298298
Ok(self.pos)
299299
}
300-
None => Err(Error::new_const(
300+
None => Err(io::const_io_error!(
301301
ErrorKind::InvalidInput,
302-
&"invalid seek to a negative or overflowing position",
302+
"invalid seek to a negative or overflowing position",
303303
)),
304304
}
305305
}
@@ -400,9 +400,9 @@ fn slice_write_vectored(
400400
// Resizing write implementation
401401
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
402402
let pos: usize = (*pos_mut).try_into().map_err(|_| {
403-
Error::new_const(
403+
io::const_io_error!(
404404
ErrorKind::InvalidInput,
405-
&"cursor position exceeds maximum possible vector length",
405+
"cursor position exceeds maximum possible vector length",
406406
)
407407
})?;
408408
// Make sure the internal buffer is as least as big as where we

library/std/src/io/error.rs

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#[cfg(test)]
22
mod tests;
33

4+
mod repr_unpacked;
5+
use repr_unpacked::Repr;
6+
47
use crate::convert::From;
58
use crate::error;
69
use crate::fmt;
@@ -66,15 +69,38 @@ impl fmt::Debug for Error {
6669
}
6770
}
6871

69-
enum Repr {
72+
enum ErrorData<C> {
7073
Os(i32),
7174
Simple(ErrorKind),
72-
// &str is a fat pointer, but &&str is a thin pointer.
73-
SimpleMessage(ErrorKind, &'static &'static str),
74-
Custom(Box<Custom>),
75+
SimpleMessage(&'static SimpleMessage),
76+
Custom(C),
77+
}
78+
79+
#[repr(align(4))]
80+
#[doc(hidden)]
81+
pub(crate) struct SimpleMessage {
82+
kind: ErrorKind,
83+
message: &'static str,
84+
}
85+
86+
impl SimpleMessage {
87+
pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self {
88+
Self { kind, message }
89+
}
90+
}
91+
92+
/// Create and return an `io::Error` for a given `ErrorKind` and constant
93+
/// message. This doesn't allocate.
94+
pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) {
95+
$crate::io::error::Error::from_static_message({
96+
const MESSAGE_DATA: $crate::io::error::SimpleMessage =
97+
$crate::io::error::SimpleMessage::new($kind, $message);
98+
&MESSAGE_DATA
99+
})
75100
}
76101

77102
#[derive(Debug)]
103+
#[repr(align(4))]
78104
struct Custom {
79105
kind: ErrorKind,
80106
error: Box<dyn error::Error + Send + Sync>,
@@ -396,7 +422,7 @@ impl From<ErrorKind> for Error {
396422
/// ```
397423
#[inline]
398424
fn from(kind: ErrorKind) -> Error {
399-
Error { repr: Repr::Simple(kind) }
425+
Error { repr: Repr::new_simple(kind) }
400426
}
401427
}
402428

@@ -461,20 +487,22 @@ impl Error {
461487
}
462488

463489
fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
464-
Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
490+
Error { repr: Repr::new_custom(Box::new(Custom { kind, error })) }
465491
}
466492

467-
/// Creates a new I/O error from a known kind of error as well as a
468-
/// constant message.
493+
/// Creates a new I/O error from a known kind of error as well as a constant
494+
/// message.
469495
///
470496
/// This function does not allocate.
471497
///
472-
/// This function should maybe change to
473-
/// `new_const<const MSG: &'static str>(kind: ErrorKind)`
474-
/// in the future, when const generics allow that.
498+
/// You should not use this directly, and instead use the `const_io_error!`
499+
/// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
500+
///
501+
/// This function should maybe change to `from_static_message<const MSG: &'static
502+
/// str>(kind: ErrorKind)` in the future, when const generics allow that.
475503
#[inline]
476-
pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
477-
Self { repr: Repr::SimpleMessage(kind, message) }
504+
pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error {
505+
Self { repr: Repr::new_simple_message(msg) }
478506
}
479507

480508
/// Returns an error representing the last OS error which occurred.
@@ -532,7 +560,7 @@ impl Error {
532560
#[must_use]
533561
#[inline]
534562
pub fn from_raw_os_error(code: i32) -> Error {
535-
Error { repr: Repr::Os(code) }
563+
Error { repr: Repr::new_os(code) }
536564
}
537565

538566
/// Returns the OS error that this error represents (if any).
@@ -568,11 +596,11 @@ impl Error {
568596
#[must_use]
569597
#[inline]
570598
pub fn raw_os_error(&self) -> Option<i32> {
571-
match self.repr {
572-
Repr::Os(i) => Some(i),
573-
Repr::Custom(..) => None,
574-
Repr::Simple(..) => None,
575-
Repr::SimpleMessage(..) => None,
599+
match self.repr.data() {
600+
ErrorData::Os(i) => Some(i),
601+
ErrorData::Custom(..) => None,
602+
ErrorData::Simple(..) => None,
603+
ErrorData::SimpleMessage(..) => None,
576604
}
577605
}
578606

@@ -607,11 +635,11 @@ impl Error {
607635
#[must_use]
608636
#[inline]
609637
pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
610-
match self.repr {
611-
Repr::Os(..) => None,
612-
Repr::Simple(..) => None,
613-
Repr::SimpleMessage(..) => None,
614-
Repr::Custom(ref c) => Some(&*c.error),
638+
match self.repr.data() {
639+
ErrorData::Os(..) => None,
640+
ErrorData::Simple(..) => None,
641+
ErrorData::SimpleMessage(..) => None,
642+
ErrorData::Custom(c) => Some(&*c.error),
615643
}
616644
}
617645

@@ -681,11 +709,11 @@ impl Error {
681709
#[must_use]
682710
#[inline]
683711
pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
684-
match self.repr {
685-
Repr::Os(..) => None,
686-
Repr::Simple(..) => None,
687-
Repr::SimpleMessage(..) => None,
688-
Repr::Custom(ref mut c) => Some(&mut *c.error),
712+
match self.repr.data_mut() {
713+
ErrorData::Os(..) => None,
714+
ErrorData::Simple(..) => None,
715+
ErrorData::SimpleMessage(..) => None,
716+
ErrorData::Custom(c) => Some(&mut *c.error),
689717
}
690718
}
691719

@@ -720,11 +748,11 @@ impl Error {
720748
#[must_use = "`self` will be dropped if the result is not used"]
721749
#[inline]
722750
pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
723-
match self.repr {
724-
Repr::Os(..) => None,
725-
Repr::Simple(..) => None,
726-
Repr::SimpleMessage(..) => None,
727-
Repr::Custom(c) => Some(c.error),
751+
match self.repr.into_data() {
752+
ErrorData::Os(..) => None,
753+
ErrorData::Simple(..) => None,
754+
ErrorData::SimpleMessage(..) => None,
755+
ErrorData::Custom(c) => Some(c.error),
728756
}
729757
}
730758

@@ -750,44 +778,46 @@ impl Error {
750778
#[must_use]
751779
#[inline]
752780
pub fn kind(&self) -> ErrorKind {
753-
match self.repr {
754-
Repr::Os(code) => sys::decode_error_kind(code),
755-
Repr::Custom(ref c) => c.kind,
756-
Repr::Simple(kind) => kind,
757-
Repr::SimpleMessage(kind, _) => kind,
781+
match self.repr.data() {
782+
ErrorData::Os(code) => sys::decode_error_kind(code),
783+
ErrorData::Custom(ref c) => c.kind,
784+
ErrorData::Simple(kind) => kind,
785+
ErrorData::SimpleMessage(m) => m.kind,
758786
}
759787
}
760788
}
761789

762790
impl fmt::Debug for Repr {
763791
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
764-
match *self {
765-
Repr::Os(code) => fmt
792+
match self.data() {
793+
ErrorData::Os(code) => fmt
766794
.debug_struct("Os")
767795
.field("code", &code)
768796
.field("kind", &sys::decode_error_kind(code))
769797
.field("message", &sys::os::error_string(code))
770798
.finish(),
771-
Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
772-
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
773-
Repr::SimpleMessage(kind, &message) => {
774-
fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
775-
}
799+
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
800+
ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
801+
ErrorData::SimpleMessage(msg) => fmt
802+
.debug_struct("Error")
803+
.field("kind", &msg.kind)
804+
.field("message", &msg.message)
805+
.finish(),
776806
}
777807
}
778808
}
779809

780810
#[stable(feature = "rust1", since = "1.0.0")]
781811
impl fmt::Display for Error {
782812
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
783-
match self.repr {
784-
Repr::Os(code) => {
813+
match self.repr.data() {
814+
ErrorData::Os(code) => {
785815
let detail = sys::os::error_string(code);
786816
write!(fmt, "{} (os error {})", detail, code)
787817
}
788-
Repr::Custom(ref c) => c.error.fmt(fmt),
789-
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
790-
Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
818+
ErrorData::Custom(ref c) => c.error.fmt(fmt),
819+
ErrorData::Simple(kind) => write!(fmt, "{}", kind.as_str()),
820+
ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
791821
}
792822
}
793823
}
@@ -796,29 +826,29 @@ impl fmt::Display for Error {
796826
impl error::Error for Error {
797827
#[allow(deprecated, deprecated_in_future)]
798828
fn description(&self) -> &str {
799-
match self.repr {
800-
Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
801-
Repr::SimpleMessage(_, &msg) => msg,
802-
Repr::Custom(ref c) => c.error.description(),
829+
match self.repr.data() {
830+
ErrorData::Os(..) | ErrorData::Simple(..) => self.kind().as_str(),
831+
ErrorData::SimpleMessage(msg) => msg.message,
832+
ErrorData::Custom(ref c) => c.error.description(),
803833
}
804834
}
805835

806836
#[allow(deprecated)]
807837
fn cause(&self) -> Option<&dyn error::Error> {
808-
match self.repr {
809-
Repr::Os(..) => None,
810-
Repr::Simple(..) => None,
811-
Repr::SimpleMessage(..) => None,
812-
Repr::Custom(ref c) => c.error.cause(),
838+
match self.repr.data() {
839+
ErrorData::Os(..) => None,
840+
ErrorData::Simple(..) => None,
841+
ErrorData::SimpleMessage(..) => None,
842+
ErrorData::Custom(ref c) => c.error.cause(),
813843
}
814844
}
815845

816846
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
817-
match self.repr {
818-
Repr::Os(..) => None,
819-
Repr::Simple(..) => None,
820-
Repr::SimpleMessage(..) => None,
821-
Repr::Custom(ref c) => c.error.source(),
847+
match self.repr.data() {
848+
ErrorData::Os(..) => None,
849+
ErrorData::Simple(..) => None,
850+
ErrorData::SimpleMessage(..) => None,
851+
ErrorData::Custom(ref c) => c.error.source(),
822852
}
823853
}
824854
}

0 commit comments

Comments
 (0)