Skip to content

Commit d2bc30b

Browse files
authored
Auto merge of #37037 - Mark-Simulacrum:stack-error, r=alexcrichton
Add conversions from `io:ErrorKind` to `io::Error` Filing to help with discussion around the possibility of doing this. Current changes are clearly backwards incompatible, but I think adding a new function (with a bikeshed on naming) like `Error::new_str` should be possible (or some other way of specializing the string error message case) to fix #36658.
2 parents 49c36bf + 99234bb commit d2bc30b

File tree

1 file changed

+48
-21
lines changed

1 file changed

+48
-21
lines changed

src/libstd/io/error.rs

+48-21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use error;
1212
use fmt;
1313
use result;
1414
use sys;
15+
use convert::From;
1516

1617
/// A specialized [`Result`](../result/enum.Result.html) type for I/O
1718
/// operations.
@@ -62,6 +63,7 @@ pub struct Error {
6263

6364
enum Repr {
6465
Os(i32),
66+
Simple(ErrorKind),
6567
Custom(Box<Custom>),
6668
}
6769

@@ -171,6 +173,43 @@ pub enum ErrorKind {
171173
__Nonexhaustive,
172174
}
173175

176+
impl ErrorKind {
177+
fn as_str(&self) -> &'static str {
178+
match *self {
179+
ErrorKind::NotFound => "entity not found",
180+
ErrorKind::PermissionDenied => "permission denied",
181+
ErrorKind::ConnectionRefused => "connection refused",
182+
ErrorKind::ConnectionReset => "connection reset",
183+
ErrorKind::ConnectionAborted => "connection aborted",
184+
ErrorKind::NotConnected => "not connected",
185+
ErrorKind::AddrInUse => "address in use",
186+
ErrorKind::AddrNotAvailable => "address not available",
187+
ErrorKind::BrokenPipe => "broken pipe",
188+
ErrorKind::AlreadyExists => "entity already exists",
189+
ErrorKind::WouldBlock => "operation would block",
190+
ErrorKind::InvalidInput => "invalid input parameter",
191+
ErrorKind::InvalidData => "invalid data",
192+
ErrorKind::TimedOut => "timed out",
193+
ErrorKind::WriteZero => "write zero",
194+
ErrorKind::Interrupted => "operation interrupted",
195+
ErrorKind::Other => "other os error",
196+
ErrorKind::UnexpectedEof => "unexpected end of file",
197+
ErrorKind::__Nonexhaustive => unreachable!()
198+
}
199+
}
200+
}
201+
202+
/// Intended for use for errors not exposed to the user, where allocating onto
203+
/// the heap (for normal construction via Error::new) is too costly.
204+
#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
205+
impl From<ErrorKind> for Error {
206+
fn from(kind: ErrorKind) -> Error {
207+
Error {
208+
repr: Repr::Simple(kind)
209+
}
210+
}
211+
}
212+
174213
impl Error {
175214
/// Creates a new I/O error from a known kind of error as well as an
176215
/// arbitrary error payload.
@@ -285,6 +324,7 @@ impl Error {
285324
match self.repr {
286325
Repr::Os(i) => Some(i),
287326
Repr::Custom(..) => None,
327+
Repr::Simple(..) => None,
288328
}
289329
}
290330

@@ -317,6 +357,7 @@ impl Error {
317357
pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
318358
match self.repr {
319359
Repr::Os(..) => None,
360+
Repr::Simple(..) => None,
320361
Repr::Custom(ref c) => Some(&*c.error),
321362
}
322363
}
@@ -387,6 +428,7 @@ impl Error {
387428
pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
388429
match self.repr {
389430
Repr::Os(..) => None,
431+
Repr::Simple(..) => None,
390432
Repr::Custom(ref mut c) => Some(&mut *c.error),
391433
}
392434
}
@@ -420,6 +462,7 @@ impl Error {
420462
pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
421463
match self.repr {
422464
Repr::Os(..) => None,
465+
Repr::Simple(..) => None,
423466
Repr::Custom(c) => Some(c.error)
424467
}
425468
}
@@ -447,6 +490,7 @@ impl Error {
447490
match self.repr {
448491
Repr::Os(code) => sys::decode_error_kind(code),
449492
Repr::Custom(ref c) => c.kind,
493+
Repr::Simple(kind) => kind,
450494
}
451495
}
452496
}
@@ -458,6 +502,7 @@ impl fmt::Debug for Repr {
458502
fmt.debug_struct("Os").field("code", code)
459503
.field("message", &sys::os::error_string(*code)).finish(),
460504
Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
505+
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
461506
}
462507
}
463508
}
@@ -471,6 +516,7 @@ impl fmt::Display for Error {
471516
write!(fmt, "{} (os error {})", detail, code)
472517
}
473518
Repr::Custom(ref c) => c.error.fmt(fmt),
519+
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
474520
}
475521
}
476522
}
@@ -479,34 +525,15 @@ impl fmt::Display for Error {
479525
impl error::Error for Error {
480526
fn description(&self) -> &str {
481527
match self.repr {
482-
Repr::Os(..) => match self.kind() {
483-
ErrorKind::NotFound => "entity not found",
484-
ErrorKind::PermissionDenied => "permission denied",
485-
ErrorKind::ConnectionRefused => "connection refused",
486-
ErrorKind::ConnectionReset => "connection reset",
487-
ErrorKind::ConnectionAborted => "connection aborted",
488-
ErrorKind::NotConnected => "not connected",
489-
ErrorKind::AddrInUse => "address in use",
490-
ErrorKind::AddrNotAvailable => "address not available",
491-
ErrorKind::BrokenPipe => "broken pipe",
492-
ErrorKind::AlreadyExists => "entity already exists",
493-
ErrorKind::WouldBlock => "operation would block",
494-
ErrorKind::InvalidInput => "invalid input parameter",
495-
ErrorKind::InvalidData => "invalid data",
496-
ErrorKind::TimedOut => "timed out",
497-
ErrorKind::WriteZero => "write zero",
498-
ErrorKind::Interrupted => "operation interrupted",
499-
ErrorKind::Other => "other os error",
500-
ErrorKind::UnexpectedEof => "unexpected end of file",
501-
ErrorKind::__Nonexhaustive => unreachable!()
502-
},
528+
Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
503529
Repr::Custom(ref c) => c.error.description(),
504530
}
505531
}
506532

507533
fn cause(&self) -> Option<&error::Error> {
508534
match self.repr {
509535
Repr::Os(..) => None,
536+
Repr::Simple(..) => None,
510537
Repr::Custom(ref c) => c.error.cause(),
511538
}
512539
}

0 commit comments

Comments
 (0)