1 #[cfg(test)]
2 mod tests;
3 
4 use crate::convert::From;
5 use crate::error;
6 use crate::fmt;
7 use crate::result;
8 use crate::sys;
9 
10 /// A specialized [`Result`] type for I/O operations.
11 ///
12 /// This type is broadly used across [`std::io`] for any operation which may
13 /// produce an error.
14 ///
15 /// This typedef is generally used to avoid writing out [`io::Error`] directly and
16 /// is otherwise a direct mapping to [`Result`].
17 ///
18 /// While usual Rust style is to import types directly, aliases of [`Result`]
19 /// often are not, to make it easier to distinguish between them. [`Result`] is
20 /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
21 /// will generally use `io::Result` instead of shadowing the [prelude]'s import
22 /// of [`std::result::Result`][`Result`].
23 ///
24 /// [`std::io`]: crate::io
25 /// [`io::Error`]: Error
26 /// [`Result`]: crate::result::Result
27 /// [prelude]: crate::prelude
28 ///
29 /// # Examples
30 ///
31 /// A convenience function that bubbles an `io::Result` to its caller:
32 ///
33 /// ```
34 /// use std::io;
35 ///
36 /// fn get_string() -> io::Result<String> {
37 ///     let mut buffer = String::new();
38 ///
39 ///     io::stdin().read_line(&mut buffer)?;
40 ///
41 ///     Ok(buffer)
42 /// }
43 /// ```
44 #[stable(feature = "rust1", since = "1.0.0")]
45 pub type Result<T> = result::Result<T, Error>;
46 
47 /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
48 /// associated traits.
49 ///
50 /// Errors mostly originate from the underlying OS, but custom instances of
51 /// `Error` can be created with crafted error messages and a particular value of
52 /// [`ErrorKind`].
53 ///
54 /// [`Read`]: crate::io::Read
55 /// [`Write`]: crate::io::Write
56 /// [`Seek`]: crate::io::Seek
57 #[stable(feature = "rust1", since = "1.0.0")]
58 pub struct Error {
59     repr: Repr,
60 }
61 
62 #[stable(feature = "rust1", since = "1.0.0")]
63 impl fmt::Debug for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result64     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65         fmt::Debug::fmt(&self.repr, f)
66     }
67 }
68 
69 enum Repr {
70     Os(i32),
71     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 }
76 
77 #[derive(Debug)]
78 struct Custom {
79     kind: ErrorKind,
80     error: Box<dyn error::Error + Send + Sync>,
81 }
82 
83 /// A list specifying general categories of I/O error.
84 ///
85 /// This list is intended to grow over time and it is not recommended to
86 /// exhaustively match against it.
87 ///
88 /// It is used with the [`io::Error`] type.
89 ///
90 /// [`io::Error`]: Error
91 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
92 #[stable(feature = "rust1", since = "1.0.0")]
93 #[allow(deprecated)]
94 #[non_exhaustive]
95 pub enum ErrorKind {
96     /// An entity was not found, often a file.
97     #[stable(feature = "rust1", since = "1.0.0")]
98     NotFound,
99     /// The operation lacked the necessary privileges to complete.
100     #[stable(feature = "rust1", since = "1.0.0")]
101     PermissionDenied,
102     /// The connection was refused by the remote server.
103     #[stable(feature = "rust1", since = "1.0.0")]
104     ConnectionRefused,
105     /// The connection was reset by the remote server.
106     #[stable(feature = "rust1", since = "1.0.0")]
107     ConnectionReset,
108     /// The remote host is not reachable.
109     #[unstable(feature = "io_error_more", issue = "86442")]
110     HostUnreachable,
111     /// The network containing the remote host is not reachable.
112     #[unstable(feature = "io_error_more", issue = "86442")]
113     NetworkUnreachable,
114     /// The connection was aborted (terminated) by the remote server.
115     #[stable(feature = "rust1", since = "1.0.0")]
116     ConnectionAborted,
117     /// The network operation failed because it was not connected yet.
118     #[stable(feature = "rust1", since = "1.0.0")]
119     NotConnected,
120     /// A socket address could not be bound because the address is already in
121     /// use elsewhere.
122     #[stable(feature = "rust1", since = "1.0.0")]
123     AddrInUse,
124     /// A nonexistent interface was requested or the requested address was not
125     /// local.
126     #[stable(feature = "rust1", since = "1.0.0")]
127     AddrNotAvailable,
128     /// The system's networking is down.
129     #[unstable(feature = "io_error_more", issue = "86442")]
130     NetworkDown,
131     /// The operation failed because a pipe was closed.
132     #[stable(feature = "rust1", since = "1.0.0")]
133     BrokenPipe,
134     /// An entity already exists, often a file.
135     #[stable(feature = "rust1", since = "1.0.0")]
136     AlreadyExists,
137     /// The operation needs to block to complete, but the blocking operation was
138     /// requested to not occur.
139     #[stable(feature = "rust1", since = "1.0.0")]
140     WouldBlock,
141     /// A filesystem object is, unexpectedly, not a directory.
142     ///
143     /// For example, a filesystem path was specified where one of the intermediate directory
144     /// components was, in fact, a plain file.
145     #[unstable(feature = "io_error_more", issue = "86442")]
146     NotADirectory,
147     /// The filesystem object is, unexpectedly, a directory.
148     ///
149     /// A directory was specified when a non-directory was expected.
150     #[unstable(feature = "io_error_more", issue = "86442")]
151     IsADirectory,
152     /// A non-empty directory was specified where an empty directory was expected.
153     #[unstable(feature = "io_error_more", issue = "86442")]
154     DirectoryNotEmpty,
155     /// The filesystem or storage medium is read-only, but a write operation was attempted.
156     #[unstable(feature = "io_error_more", issue = "86442")]
157     ReadOnlyFilesystem,
158     /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
159     ///
160     /// There was a loop (or excessively long chain) resolving a filesystem object
161     /// or file IO object.
162     ///
163     /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
164     /// system-specific limit on the depth of symlink traversal.
165     #[unstable(feature = "io_error_more", issue = "86442")]
166     FilesystemLoop,
167     /// Stale network file handle.
168     ///
169     /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
170     /// by problems with the network or server.
171     #[unstable(feature = "io_error_more", issue = "86442")]
172     StaleNetworkFileHandle,
173     /// A parameter was incorrect.
174     #[stable(feature = "rust1", since = "1.0.0")]
175     InvalidInput,
176     /// Data not valid for the operation were encountered.
177     ///
178     /// Unlike [`InvalidInput`], this typically means that the operation
179     /// parameters were valid, however the error was caused by malformed
180     /// input data.
181     ///
182     /// For example, a function that reads a file into a string will error with
183     /// `InvalidData` if the file's contents are not valid UTF-8.
184     ///
185     /// [`InvalidInput`]: ErrorKind::InvalidInput
186     #[stable(feature = "io_invalid_data", since = "1.2.0")]
187     InvalidData,
188     /// The I/O operation's timeout expired, causing it to be canceled.
189     #[stable(feature = "rust1", since = "1.0.0")]
190     TimedOut,
191     /// An error returned when an operation could not be completed because a
192     /// call to [`write`] returned [`Ok(0)`].
193     ///
194     /// This typically means that an operation could only succeed if it wrote a
195     /// particular number of bytes but only a smaller number of bytes could be
196     /// written.
197     ///
198     /// [`write`]: crate::io::Write::write
199     /// [`Ok(0)`]: Ok
200     #[stable(feature = "rust1", since = "1.0.0")]
201     WriteZero,
202     /// The underlying storage (typically, a filesystem) is full.
203     ///
204     /// This does not include out of quota errors.
205     #[unstable(feature = "io_error_more", issue = "86442")]
206     StorageFull,
207     /// Seek on unseekable file.
208     ///
209     /// Seeking was attempted on an open file handle which is not suitable for seeking - for
210     /// example, on Unix, a named pipe opened with `File::open`.
211     #[unstable(feature = "io_error_more", issue = "86442")]
212     NotSeekable,
213     /// Filesystem quota was exceeded.
214     #[unstable(feature = "io_error_more", issue = "86442")]
215     FilesystemQuotaExceeded,
216     /// File larger than allowed or supported.
217     ///
218     /// This might arise from a hard limit of the underlying filesystem or file access API, or from
219     /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
220     /// their own errors.
221     #[unstable(feature = "io_error_more", issue = "86442")]
222     FileTooLarge,
223     /// Resource is busy.
224     #[unstable(feature = "io_error_more", issue = "86442")]
225     ResourceBusy,
226     /// Executable file is busy.
227     ///
228     /// An attempt was made to write to a file which is also in use as a running program.  (Not all
229     /// operating systems detect this situation.)
230     #[unstable(feature = "io_error_more", issue = "86442")]
231     ExecutableFileBusy,
232     /// Deadlock (avoided).
233     ///
234     /// A file locking operation would result in deadlock.  This situation is typically detected, if
235     /// at all, on a best-effort basis.
236     #[unstable(feature = "io_error_more", issue = "86442")]
237     Deadlock,
238     /// Cross-device or cross-filesystem (hard) link or rename.
239     #[unstable(feature = "io_error_more", issue = "86442")]
240     CrossesDevices,
241     /// Too many (hard) links to the same filesystem object.
242     ///
243     /// The filesystem does not support making so many hardlinks to the same file.
244     #[unstable(feature = "io_error_more", issue = "86442")]
245     TooManyLinks,
246     /// Filename too long.
247     ///
248     /// The limit might be from the underlying filesystem or API, or an administratively imposed
249     /// resource limit.
250     #[unstable(feature = "io_error_more", issue = "86442")]
251     FilenameTooLong,
252     /// Program argument list too long.
253     ///
254     /// When trying to run an external program, a system or process limit on the size of the
255     /// arguments would have been exceeded.
256     #[unstable(feature = "io_error_more", issue = "86442")]
257     ArgumentListTooLong,
258     /// This operation was interrupted.
259     ///
260     /// Interrupted operations can typically be retried.
261     #[stable(feature = "rust1", since = "1.0.0")]
262     Interrupted,
263 
264     /// This operation is unsupported on this platform.
265     ///
266     /// This means that the operation can never succeed.
267     #[stable(feature = "unsupported_error", since = "1.53.0")]
268     Unsupported,
269 
270     // ErrorKinds which are primarily categorisations for OS error
271     // codes should be added above.
272     //
273     /// An error returned when an operation could not be completed because an
274     /// "end of file" was reached prematurely.
275     ///
276     /// This typically means that an operation could only succeed if it read a
277     /// particular number of bytes but only a smaller number of bytes could be
278     /// read.
279     #[stable(feature = "read_exact", since = "1.6.0")]
280     UnexpectedEof,
281 
282     /// An operation could not be completed, because it failed
283     /// to allocate enough memory.
284     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
285     OutOfMemory,
286 
287     // "Unusual" error kinds which do not correspond simply to (sets
288     // of) OS error codes, should be added just above this comment.
289     // `Other` and `Uncategorised` should remain at the end:
290     //
291     /// A custom error that does not fall under any other I/O error kind.
292     ///
293     /// This can be used to construct your own [`Error`]s that do not match any
294     /// [`ErrorKind`].
295     ///
296     /// This [`ErrorKind`] is not used by the standard library.
297     ///
298     /// Errors from the standard library that do not fall under any of the I/O
299     /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
300     /// New [`ErrorKind`]s might be added in the future for some of those.
301     #[stable(feature = "rust1", since = "1.0.0")]
302     Other,
303 
304     /// Any I/O error from the standard library that's not part of this list.
305     ///
306     /// Errors that are `Uncategorized` now may move to a different or a new
307     /// [`ErrorKind`] variant in the future. It is not recommended to match
308     /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
309     #[unstable(feature = "io_error_uncategorized", issue = "none")]
310     #[doc(hidden)]
311     Uncategorized,
312 }
313 
314 impl ErrorKind {
as_str(&self) -> &'static str315     pub(crate) fn as_str(&self) -> &'static str {
316         use ErrorKind::*;
317         // Strictly alphabetical, please.  (Sadly rustfmt cannot do this yet.)
318         match *self {
319             AddrInUse => "address in use",
320             AddrNotAvailable => "address not available",
321             AlreadyExists => "entity already exists",
322             ArgumentListTooLong => "argument list too long",
323             BrokenPipe => "broken pipe",
324             ConnectionAborted => "connection aborted",
325             ConnectionRefused => "connection refused",
326             ConnectionReset => "connection reset",
327             CrossesDevices => "cross-device link or rename",
328             Deadlock => "deadlock",
329             DirectoryNotEmpty => "directory not empty",
330             ExecutableFileBusy => "executable file busy",
331             FileTooLarge => "file too large",
332             FilenameTooLong => "filename too long",
333             FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
334             FilesystemQuotaExceeded => "filesystem quota exceeded",
335             HostUnreachable => "host unreachable",
336             Interrupted => "operation interrupted",
337             InvalidData => "invalid data",
338             InvalidInput => "invalid input parameter",
339             IsADirectory => "is a directory",
340             NetworkDown => "network down",
341             NetworkUnreachable => "network unreachable",
342             NotADirectory => "not a directory",
343             NotConnected => "not connected",
344             NotFound => "entity not found",
345             NotSeekable => "seek on unseekable file",
346             Other => "other error",
347             OutOfMemory => "out of memory",
348             PermissionDenied => "permission denied",
349             ReadOnlyFilesystem => "read-only filesystem or storage medium",
350             ResourceBusy => "resource busy",
351             StaleNetworkFileHandle => "stale network file handle",
352             StorageFull => "no storage space",
353             TimedOut => "timed out",
354             TooManyLinks => "too many links",
355             Uncategorized => "uncategorized error",
356             UnexpectedEof => "unexpected end of file",
357             Unsupported => "unsupported",
358             WouldBlock => "operation would block",
359             WriteZero => "write zero",
360         }
361     }
362 }
363 
364 /// Intended for use for errors not exposed to the user, where allocating onto
365 /// the heap (for normal construction via Error::new) is too costly.
366 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
367 impl From<ErrorKind> for Error {
368     /// Converts an [`ErrorKind`] into an [`Error`].
369     ///
370     /// This conversion allocates a new error with a simple representation of error kind.
371     ///
372     /// # Examples
373     ///
374     /// ```
375     /// use std::io::{Error, ErrorKind};
376     ///
377     /// let not_found = ErrorKind::NotFound;
378     /// let error = Error::from(not_found);
379     /// assert_eq!("entity not found", format!("{}", error));
380     /// ```
381     #[inline]
from(kind: ErrorKind) -> Error382     fn from(kind: ErrorKind) -> Error {
383         Error { repr: Repr::Simple(kind) }
384     }
385 }
386 
387 impl Error {
388     /// Creates a new I/O error from a known kind of error as well as an
389     /// arbitrary error payload.
390     ///
391     /// This function is used to generically create I/O errors which do not
392     /// originate from the OS itself. The `error` argument is an arbitrary
393     /// payload which will be contained in this [`Error`].
394     ///
395     /// If no extra payload is required, use the `From` conversion from
396     /// `ErrorKind`.
397     ///
398     /// # Examples
399     ///
400     /// ```
401     /// use std::io::{Error, ErrorKind};
402     ///
403     /// // errors can be created from strings
404     /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
405     ///
406     /// // errors can also be created from other errors
407     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
408     ///
409     /// // creating an error without payload
410     /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
411     /// ```
412     #[stable(feature = "rust1", since = "1.0.0")]
new<E>(kind: ErrorKind, error: E) -> Error where E: Into<Box<dyn error::Error + Send + Sync>>,413     pub fn new<E>(kind: ErrorKind, error: E) -> Error
414     where
415         E: Into<Box<dyn error::Error + Send + Sync>>,
416     {
417         Self::_new(kind, error.into())
418     }
419 
_new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error420     fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
421         Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
422     }
423 
424     /// Creates a new I/O error from a known kind of error as well as a
425     /// constant message.
426     ///
427     /// This function does not allocate.
428     ///
429     /// This function should maybe change to
430     /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
431     /// in the future, when const generics allow that.
432     #[inline]
new_const(kind: ErrorKind, message: &'static &'static str) -> Error433     pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
434         Self { repr: Repr::SimpleMessage(kind, message) }
435     }
436 
437     /// Returns an error representing the last OS error which occurred.
438     ///
439     /// This function reads the value of `errno` for the target platform (e.g.
440     /// `GetLastError` on Windows) and will return a corresponding instance of
441     /// [`Error`] for the error code.
442     ///
443     /// # Examples
444     ///
445     /// ```
446     /// use std::io::Error;
447     ///
448     /// println!("last OS error: {:?}", Error::last_os_error());
449     /// ```
450     #[stable(feature = "rust1", since = "1.0.0")]
451     #[must_use]
452     #[inline]
last_os_error() -> Error453     pub fn last_os_error() -> Error {
454         Error::from_raw_os_error(sys::os::errno() as i32)
455     }
456 
457     /// Creates a new instance of an [`Error`] from a particular OS error code.
458     ///
459     /// # Examples
460     ///
461     /// On Linux:
462     ///
463     /// ```
464     /// # if cfg!(target_os = "linux") {
465     /// use std::io;
466     ///
467     /// let error = io::Error::from_raw_os_error(22);
468     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
469     /// # }
470     /// ```
471     ///
472     /// On Windows:
473     ///
474     /// ```
475     /// # if cfg!(windows) {
476     /// use std::io;
477     ///
478     /// let error = io::Error::from_raw_os_error(10022);
479     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
480     /// # }
481     /// ```
482     #[stable(feature = "rust1", since = "1.0.0")]
483     #[must_use]
484     #[inline]
from_raw_os_error(code: i32) -> Error485     pub fn from_raw_os_error(code: i32) -> Error {
486         Error { repr: Repr::Os(code) }
487     }
488 
489     /// Returns the OS error that this error represents (if any).
490     ///
491     /// If this [`Error`] was constructed via [`last_os_error`] or
492     /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
493     /// it will return [`None`].
494     ///
495     /// [`last_os_error`]: Error::last_os_error
496     /// [`from_raw_os_error`]: Error::from_raw_os_error
497     ///
498     /// # Examples
499     ///
500     /// ```
501     /// use std::io::{Error, ErrorKind};
502     ///
503     /// fn print_os_error(err: &Error) {
504     ///     if let Some(raw_os_err) = err.raw_os_error() {
505     ///         println!("raw OS error: {:?}", raw_os_err);
506     ///     } else {
507     ///         println!("Not an OS error");
508     ///     }
509     /// }
510     ///
511     /// fn main() {
512     ///     // Will print "raw OS error: ...".
513     ///     print_os_error(&Error::last_os_error());
514     ///     // Will print "Not an OS error".
515     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
516     /// }
517     /// ```
518     #[stable(feature = "rust1", since = "1.0.0")]
519     #[must_use]
520     #[inline]
raw_os_error(&self) -> Option<i32>521     pub fn raw_os_error(&self) -> Option<i32> {
522         match self.repr {
523             Repr::Os(i) => Some(i),
524             Repr::Custom(..) => None,
525             Repr::Simple(..) => None,
526             Repr::SimpleMessage(..) => None,
527         }
528     }
529 
530     /// Returns a reference to the inner error wrapped by this error (if any).
531     ///
532     /// If this [`Error`] was constructed via [`new`] then this function will
533     /// return [`Some`], otherwise it will return [`None`].
534     ///
535     /// [`new`]: Error::new
536     ///
537     /// # Examples
538     ///
539     /// ```
540     /// use std::io::{Error, ErrorKind};
541     ///
542     /// fn print_error(err: &Error) {
543     ///     if let Some(inner_err) = err.get_ref() {
544     ///         println!("Inner error: {:?}", inner_err);
545     ///     } else {
546     ///         println!("No inner error");
547     ///     }
548     /// }
549     ///
550     /// fn main() {
551     ///     // Will print "No inner error".
552     ///     print_error(&Error::last_os_error());
553     ///     // Will print "Inner error: ...".
554     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
555     /// }
556     /// ```
557     #[stable(feature = "io_error_inner", since = "1.3.0")]
558     #[must_use]
559     #[inline]
get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)>560     pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
561         match self.repr {
562             Repr::Os(..) => None,
563             Repr::Simple(..) => None,
564             Repr::SimpleMessage(..) => None,
565             Repr::Custom(ref c) => Some(&*c.error),
566         }
567     }
568 
569     /// Returns a mutable reference to the inner error wrapped by this error
570     /// (if any).
571     ///
572     /// If this [`Error`] was constructed via [`new`] then this function will
573     /// return [`Some`], otherwise it will return [`None`].
574     ///
575     /// [`new`]: Error::new
576     ///
577     /// # Examples
578     ///
579     /// ```
580     /// use std::io::{Error, ErrorKind};
581     /// use std::{error, fmt};
582     /// use std::fmt::Display;
583     ///
584     /// #[derive(Debug)]
585     /// struct MyError {
586     ///     v: String,
587     /// }
588     ///
589     /// impl MyError {
590     ///     fn new() -> MyError {
591     ///         MyError {
592     ///             v: "oh no!".to_string()
593     ///         }
594     ///     }
595     ///
596     ///     fn change_message(&mut self, new_message: &str) {
597     ///         self.v = new_message.to_string();
598     ///     }
599     /// }
600     ///
601     /// impl error::Error for MyError {}
602     ///
603     /// impl Display for MyError {
604     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
605     ///         write!(f, "MyError: {}", &self.v)
606     ///     }
607     /// }
608     ///
609     /// fn change_error(mut err: Error) -> Error {
610     ///     if let Some(inner_err) = err.get_mut() {
611     ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
612     ///     }
613     ///     err
614     /// }
615     ///
616     /// fn print_error(err: &Error) {
617     ///     if let Some(inner_err) = err.get_ref() {
618     ///         println!("Inner error: {}", inner_err);
619     ///     } else {
620     ///         println!("No inner error");
621     ///     }
622     /// }
623     ///
624     /// fn main() {
625     ///     // Will print "No inner error".
626     ///     print_error(&change_error(Error::last_os_error()));
627     ///     // Will print "Inner error: ...".
628     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
629     /// }
630     /// ```
631     #[stable(feature = "io_error_inner", since = "1.3.0")]
632     #[must_use]
633     #[inline]
get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)>634     pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
635         match self.repr {
636             Repr::Os(..) => None,
637             Repr::Simple(..) => None,
638             Repr::SimpleMessage(..) => None,
639             Repr::Custom(ref mut c) => Some(&mut *c.error),
640         }
641     }
642 
643     /// Consumes the `Error`, returning its inner error (if any).
644     ///
645     /// If this [`Error`] was constructed via [`new`] then this function will
646     /// return [`Some`], otherwise it will return [`None`].
647     ///
648     /// [`new`]: Error::new
649     ///
650     /// # Examples
651     ///
652     /// ```
653     /// use std::io::{Error, ErrorKind};
654     ///
655     /// fn print_error(err: Error) {
656     ///     if let Some(inner_err) = err.into_inner() {
657     ///         println!("Inner error: {}", inner_err);
658     ///     } else {
659     ///         println!("No inner error");
660     ///     }
661     /// }
662     ///
663     /// fn main() {
664     ///     // Will print "No inner error".
665     ///     print_error(Error::last_os_error());
666     ///     // Will print "Inner error: ...".
667     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
668     /// }
669     /// ```
670     #[stable(feature = "io_error_inner", since = "1.3.0")]
671     #[must_use = "`self` will be dropped if the result is not used"]
672     #[inline]
into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>>673     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
674         match self.repr {
675             Repr::Os(..) => None,
676             Repr::Simple(..) => None,
677             Repr::SimpleMessage(..) => None,
678             Repr::Custom(c) => Some(c.error),
679         }
680     }
681 
682     /// Returns the corresponding [`ErrorKind`] for this error.
683     ///
684     /// # Examples
685     ///
686     /// ```
687     /// use std::io::{Error, ErrorKind};
688     ///
689     /// fn print_error(err: Error) {
690     ///     println!("{:?}", err.kind());
691     /// }
692     ///
693     /// fn main() {
694     ///     // Will print "Uncategorized".
695     ///     print_error(Error::last_os_error());
696     ///     // Will print "AddrInUse".
697     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
698     /// }
699     /// ```
700     #[stable(feature = "rust1", since = "1.0.0")]
701     #[must_use]
702     #[inline]
kind(&self) -> ErrorKind703     pub fn kind(&self) -> ErrorKind {
704         match self.repr {
705             Repr::Os(code) => sys::decode_error_kind(code),
706             Repr::Custom(ref c) => c.kind,
707             Repr::Simple(kind) => kind,
708             Repr::SimpleMessage(kind, _) => kind,
709         }
710     }
711 }
712 
713 impl fmt::Debug for Repr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result714     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
715         match *self {
716             Repr::Os(code) => fmt
717                 .debug_struct("Os")
718                 .field("code", &code)
719                 .field("kind", &sys::decode_error_kind(code))
720                 .field("message", &sys::os::error_string(code))
721                 .finish(),
722             Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
723             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
724             Repr::SimpleMessage(kind, &message) => {
725                 fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
726             }
727         }
728     }
729 }
730 
731 #[stable(feature = "rust1", since = "1.0.0")]
732 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result733     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
734         match self.repr {
735             Repr::Os(code) => {
736                 let detail = sys::os::error_string(code);
737                 write!(fmt, "{} (os error {})", detail, code)
738             }
739             Repr::Custom(ref c) => c.error.fmt(fmt),
740             Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
741             Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
742         }
743     }
744 }
745 
746 #[stable(feature = "rust1", since = "1.0.0")]
747 impl error::Error for Error {
748     #[allow(deprecated, deprecated_in_future)]
description(&self) -> &str749     fn description(&self) -> &str {
750         match self.repr {
751             Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
752             Repr::SimpleMessage(_, &msg) => msg,
753             Repr::Custom(ref c) => c.error.description(),
754         }
755     }
756 
757     #[allow(deprecated)]
cause(&self) -> Option<&dyn error::Error>758     fn cause(&self) -> Option<&dyn error::Error> {
759         match self.repr {
760             Repr::Os(..) => None,
761             Repr::Simple(..) => None,
762             Repr::SimpleMessage(..) => None,
763             Repr::Custom(ref c) => c.error.cause(),
764         }
765     }
766 
source(&self) -> Option<&(dyn error::Error + 'static)>767     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
768         match self.repr {
769             Repr::Os(..) => None,
770             Repr::Simple(..) => None,
771             Repr::SimpleMessage(..) => None,
772             Repr::Custom(ref c) => c.error.source(),
773         }
774     }
775 }
776 
_assert_error_is_sync_send()777 fn _assert_error_is_sync_send() {
778     fn _is_sync_send<T: Sync + Send>() {}
779     _is_sync_send::<Error>();
780 }
781