• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[cfg(test)]
2 mod tests;
3 
4 #[cfg(target_pointer_width = "64")]
5 mod repr_bitpacked;
6 #[cfg(target_pointer_width = "64")]
7 use repr_bitpacked::Repr;
8 
9 #[cfg(not(target_pointer_width = "64"))]
10 mod repr_unpacked;
11 #[cfg(not(target_pointer_width = "64"))]
12 use repr_unpacked::Repr;
13 
14 use crate::error;
15 use crate::fmt;
16 use crate::result;
17 use crate::sys;
18 
19 /// A specialized [`Result`] type for I/O operations.
20 ///
21 /// This type is broadly used across [`std::io`] for any operation which may
22 /// produce an error.
23 ///
24 /// This typedef is generally used to avoid writing out [`io::Error`] directly and
25 /// is otherwise a direct mapping to [`Result`].
26 ///
27 /// While usual Rust style is to import types directly, aliases of [`Result`]
28 /// often are not, to make it easier to distinguish between them. [`Result`] is
29 /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
30 /// will generally use `io::Result` instead of shadowing the [prelude]'s import
31 /// of [`std::result::Result`][`Result`].
32 ///
33 /// [`std::io`]: crate::io
34 /// [`io::Error`]: Error
35 /// [`Result`]: crate::result::Result
36 /// [prelude]: crate::prelude
37 ///
38 /// # Examples
39 ///
40 /// A convenience function that bubbles an `io::Result` to its caller:
41 ///
42 /// ```
43 /// use std::io;
44 ///
45 /// fn get_string() -> io::Result<String> {
46 ///     let mut buffer = String::new();
47 ///
48 ///     io::stdin().read_line(&mut buffer)?;
49 ///
50 ///     Ok(buffer)
51 /// }
52 /// ```
53 #[stable(feature = "rust1", since = "1.0.0")]
54 pub type Result<T> = result::Result<T, Error>;
55 
56 /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
57 /// associated traits.
58 ///
59 /// Errors mostly originate from the underlying OS, but custom instances of
60 /// `Error` can be created with crafted error messages and a particular value of
61 /// [`ErrorKind`].
62 ///
63 /// [`Read`]: crate::io::Read
64 /// [`Write`]: crate::io::Write
65 /// [`Seek`]: crate::io::Seek
66 #[stable(feature = "rust1", since = "1.0.0")]
67 pub struct Error {
68     repr: Repr,
69 }
70 
71 #[stable(feature = "rust1", since = "1.0.0")]
72 impl fmt::Debug for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result73     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74         fmt::Debug::fmt(&self.repr, f)
75     }
76 }
77 
78 #[stable(feature = "rust1", since = "1.0.0")]
79 impl From<alloc::ffi::NulError> for Error {
80     /// Converts a [`alloc::ffi::NulError`] into a [`Error`].
from(_: alloc::ffi::NulError) -> Error81     fn from(_: alloc::ffi::NulError) -> Error {
82         const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
83     }
84 }
85 
86 // Only derive debug in tests, to make sure it
87 // doesn't accidentally get printed.
88 #[cfg_attr(test, derive(Debug))]
89 enum ErrorData<C> {
90     Os(RawOsError),
91     Simple(ErrorKind),
92     SimpleMessage(&'static SimpleMessage),
93     Custom(C),
94 }
95 
96 /// The type of raw OS error codes returned by [`Error::raw_os_error`].
97 ///
98 /// This is an [`i32`] on all currently supported platforms, but platforms
99 /// added in the future (such as UEFI) may use a different primitive type like
100 /// [`usize`]. Use `as`or [`into`] conversions where applicable to ensure maximum
101 /// portability.
102 ///
103 /// [`into`]: Into::into
104 #[unstable(feature = "raw_os_error_ty", issue = "107792")]
105 pub type RawOsError = i32;
106 
107 // `#[repr(align(4))]` is probably redundant, it should have that value or
108 // higher already. We include it just because repr_bitpacked.rs's encoding
109 // requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
110 // alignment required by the struct, only increase it).
111 //
112 // If we add more variants to ErrorData, this can be increased to 8, but it
113 // should probably be behind `#[cfg_attr(target_pointer_width = "64", ...)]` or
114 // whatever cfg we're using to enable the `repr_bitpacked` code, since only the
115 // that version needs the alignment, and 8 is higher than the alignment we'll
116 // have on 32 bit platforms.
117 //
118 // (For the sake of being explicit: the alignment requirement here only matters
119 // if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't
120 // matter at all)
121 #[repr(align(4))]
122 #[derive(Debug)]
123 pub(crate) struct SimpleMessage {
124     kind: ErrorKind,
125     message: &'static str,
126 }
127 
128 impl SimpleMessage {
new(kind: ErrorKind, message: &'static str) -> Self129     pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self {
130         Self { kind, message }
131     }
132 }
133 
134 /// Create and return an `io::Error` for a given `ErrorKind` and constant
135 /// message. This doesn't allocate.
136 pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) {
137     $crate::io::error::Error::from_static_message({
138         const MESSAGE_DATA: $crate::io::error::SimpleMessage =
139             $crate::io::error::SimpleMessage::new($kind, $message);
140         &MESSAGE_DATA
141     })
142 }
143 
144 // As with `SimpleMessage`: `#[repr(align(4))]` here is just because
145 // repr_bitpacked's encoding requires it. In practice it almost certainly be
146 // already be this high or higher.
147 #[derive(Debug)]
148 #[repr(align(4))]
149 struct Custom {
150     kind: ErrorKind,
151     error: Box<dyn error::Error + Send + Sync>,
152 }
153 
154 /// A list specifying general categories of I/O error.
155 ///
156 /// This list is intended to grow over time and it is not recommended to
157 /// exhaustively match against it.
158 ///
159 /// It is used with the [`io::Error`] type.
160 ///
161 /// [`io::Error`]: Error
162 ///
163 /// # Handling errors and matching on `ErrorKind`
164 ///
165 /// In application code, use `match` for the `ErrorKind` values you are
166 /// expecting; use `_` to match "all other errors".
167 ///
168 /// In comprehensive and thorough tests that want to verify that a test doesn't
169 /// return any known incorrect error kind, you may want to cut-and-paste the
170 /// current full list of errors from here into your test code, and then match
171 /// `_` as the correct case. This seems counterintuitive, but it will make your
172 /// tests more robust. In particular, if you want to verify that your code does
173 /// produce an unrecognized error kind, the robust solution is to check for all
174 /// the recognized error kinds and fail in those cases.
175 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
176 #[stable(feature = "rust1", since = "1.0.0")]
177 #[allow(deprecated)]
178 #[non_exhaustive]
179 pub enum ErrorKind {
180     /// An entity was not found, often a file.
181     #[stable(feature = "rust1", since = "1.0.0")]
182     NotFound,
183     /// The operation lacked the necessary privileges to complete.
184     #[stable(feature = "rust1", since = "1.0.0")]
185     PermissionDenied,
186     /// The connection was refused by the remote server.
187     #[stable(feature = "rust1", since = "1.0.0")]
188     ConnectionRefused,
189     /// The connection was reset by the remote server.
190     #[stable(feature = "rust1", since = "1.0.0")]
191     ConnectionReset,
192     /// The remote host is not reachable.
193     #[unstable(feature = "io_error_more", issue = "86442")]
194     HostUnreachable,
195     /// The network containing the remote host is not reachable.
196     #[unstable(feature = "io_error_more", issue = "86442")]
197     NetworkUnreachable,
198     /// The connection was aborted (terminated) by the remote server.
199     #[stable(feature = "rust1", since = "1.0.0")]
200     ConnectionAborted,
201     /// The network operation failed because it was not connected yet.
202     #[stable(feature = "rust1", since = "1.0.0")]
203     NotConnected,
204     /// A socket address could not be bound because the address is already in
205     /// use elsewhere.
206     #[stable(feature = "rust1", since = "1.0.0")]
207     AddrInUse,
208     /// A nonexistent interface was requested or the requested address was not
209     /// local.
210     #[stable(feature = "rust1", since = "1.0.0")]
211     AddrNotAvailable,
212     /// The system's networking is down.
213     #[unstable(feature = "io_error_more", issue = "86442")]
214     NetworkDown,
215     /// The operation failed because a pipe was closed.
216     #[stable(feature = "rust1", since = "1.0.0")]
217     BrokenPipe,
218     /// An entity already exists, often a file.
219     #[stable(feature = "rust1", since = "1.0.0")]
220     AlreadyExists,
221     /// The operation needs to block to complete, but the blocking operation was
222     /// requested to not occur.
223     #[stable(feature = "rust1", since = "1.0.0")]
224     WouldBlock,
225     /// A filesystem object is, unexpectedly, not a directory.
226     ///
227     /// For example, a filesystem path was specified where one of the intermediate directory
228     /// components was, in fact, a plain file.
229     #[unstable(feature = "io_error_more", issue = "86442")]
230     NotADirectory,
231     /// The filesystem object is, unexpectedly, a directory.
232     ///
233     /// A directory was specified when a non-directory was expected.
234     #[unstable(feature = "io_error_more", issue = "86442")]
235     IsADirectory,
236     /// A non-empty directory was specified where an empty directory was expected.
237     #[unstable(feature = "io_error_more", issue = "86442")]
238     DirectoryNotEmpty,
239     /// The filesystem or storage medium is read-only, but a write operation was attempted.
240     #[unstable(feature = "io_error_more", issue = "86442")]
241     ReadOnlyFilesystem,
242     /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
243     ///
244     /// There was a loop (or excessively long chain) resolving a filesystem object
245     /// or file IO object.
246     ///
247     /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
248     /// system-specific limit on the depth of symlink traversal.
249     #[unstable(feature = "io_error_more", issue = "86442")]
250     FilesystemLoop,
251     /// Stale network file handle.
252     ///
253     /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
254     /// by problems with the network or server.
255     #[unstable(feature = "io_error_more", issue = "86442")]
256     StaleNetworkFileHandle,
257     /// A parameter was incorrect.
258     #[stable(feature = "rust1", since = "1.0.0")]
259     InvalidInput,
260     /// Data not valid for the operation were encountered.
261     ///
262     /// Unlike [`InvalidInput`], this typically means that the operation
263     /// parameters were valid, however the error was caused by malformed
264     /// input data.
265     ///
266     /// For example, a function that reads a file into a string will error with
267     /// `InvalidData` if the file's contents are not valid UTF-8.
268     ///
269     /// [`InvalidInput`]: ErrorKind::InvalidInput
270     #[stable(feature = "io_invalid_data", since = "1.2.0")]
271     InvalidData,
272     /// The I/O operation's timeout expired, causing it to be canceled.
273     #[stable(feature = "rust1", since = "1.0.0")]
274     TimedOut,
275     /// An error returned when an operation could not be completed because a
276     /// call to [`write`] returned [`Ok(0)`].
277     ///
278     /// This typically means that an operation could only succeed if it wrote a
279     /// particular number of bytes but only a smaller number of bytes could be
280     /// written.
281     ///
282     /// [`write`]: crate::io::Write::write
283     /// [`Ok(0)`]: Ok
284     #[stable(feature = "rust1", since = "1.0.0")]
285     WriteZero,
286     /// The underlying storage (typically, a filesystem) is full.
287     ///
288     /// This does not include out of quota errors.
289     #[unstable(feature = "io_error_more", issue = "86442")]
290     StorageFull,
291     /// Seek on unseekable file.
292     ///
293     /// Seeking was attempted on an open file handle which is not suitable for seeking - for
294     /// example, on Unix, a named pipe opened with `File::open`.
295     #[unstable(feature = "io_error_more", issue = "86442")]
296     NotSeekable,
297     /// Filesystem quota was exceeded.
298     #[unstable(feature = "io_error_more", issue = "86442")]
299     FilesystemQuotaExceeded,
300     /// File larger than allowed or supported.
301     ///
302     /// This might arise from a hard limit of the underlying filesystem or file access API, or from
303     /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
304     /// their own errors.
305     #[unstable(feature = "io_error_more", issue = "86442")]
306     FileTooLarge,
307     /// Resource is busy.
308     #[unstable(feature = "io_error_more", issue = "86442")]
309     ResourceBusy,
310     /// Executable file is busy.
311     ///
312     /// An attempt was made to write to a file which is also in use as a running program.  (Not all
313     /// operating systems detect this situation.)
314     #[unstable(feature = "io_error_more", issue = "86442")]
315     ExecutableFileBusy,
316     /// Deadlock (avoided).
317     ///
318     /// A file locking operation would result in deadlock.  This situation is typically detected, if
319     /// at all, on a best-effort basis.
320     #[unstable(feature = "io_error_more", issue = "86442")]
321     Deadlock,
322     /// Cross-device or cross-filesystem (hard) link or rename.
323     #[unstable(feature = "io_error_more", issue = "86442")]
324     CrossesDevices,
325     /// Too many (hard) links to the same filesystem object.
326     ///
327     /// The filesystem does not support making so many hardlinks to the same file.
328     #[unstable(feature = "io_error_more", issue = "86442")]
329     TooManyLinks,
330     /// A filename was invalid.
331     ///
332     /// This error can also cause if it exceeded the filename length limit.
333     #[unstable(feature = "io_error_more", issue = "86442")]
334     InvalidFilename,
335     /// Program argument list too long.
336     ///
337     /// When trying to run an external program, a system or process limit on the size of the
338     /// arguments would have been exceeded.
339     #[unstable(feature = "io_error_more", issue = "86442")]
340     ArgumentListTooLong,
341     /// This operation was interrupted.
342     ///
343     /// Interrupted operations can typically be retried.
344     #[stable(feature = "rust1", since = "1.0.0")]
345     Interrupted,
346 
347     /// This operation is unsupported on this platform.
348     ///
349     /// This means that the operation can never succeed.
350     #[stable(feature = "unsupported_error", since = "1.53.0")]
351     Unsupported,
352 
353     // ErrorKinds which are primarily categorisations for OS error
354     // codes should be added above.
355     //
356     /// An error returned when an operation could not be completed because an
357     /// "end of file" was reached prematurely.
358     ///
359     /// This typically means that an operation could only succeed if it read a
360     /// particular number of bytes but only a smaller number of bytes could be
361     /// read.
362     #[stable(feature = "read_exact", since = "1.6.0")]
363     UnexpectedEof,
364 
365     /// An operation could not be completed, because it failed
366     /// to allocate enough memory.
367     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
368     OutOfMemory,
369 
370     // "Unusual" error kinds which do not correspond simply to (sets
371     // of) OS error codes, should be added just above this comment.
372     // `Other` and `Uncategorized` should remain at the end:
373     //
374     /// A custom error that does not fall under any other I/O error kind.
375     ///
376     /// This can be used to construct your own [`Error`]s that do not match any
377     /// [`ErrorKind`].
378     ///
379     /// This [`ErrorKind`] is not used by the standard library.
380     ///
381     /// Errors from the standard library that do not fall under any of the I/O
382     /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
383     /// New [`ErrorKind`]s might be added in the future for some of those.
384     #[stable(feature = "rust1", since = "1.0.0")]
385     Other,
386 
387     /// Any I/O error from the standard library that's not part of this list.
388     ///
389     /// Errors that are `Uncategorized` now may move to a different or a new
390     /// [`ErrorKind`] variant in the future. It is not recommended to match
391     /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
392     #[unstable(feature = "io_error_uncategorized", issue = "none")]
393     #[doc(hidden)]
394     Uncategorized,
395 }
396 
397 impl ErrorKind {
as_str(&self) -> &'static str398     pub(crate) fn as_str(&self) -> &'static str {
399         use ErrorKind::*;
400         // tidy-alphabetical-start
401         match *self {
402             AddrInUse => "address in use",
403             AddrNotAvailable => "address not available",
404             AlreadyExists => "entity already exists",
405             ArgumentListTooLong => "argument list too long",
406             BrokenPipe => "broken pipe",
407             ConnectionAborted => "connection aborted",
408             ConnectionRefused => "connection refused",
409             ConnectionReset => "connection reset",
410             CrossesDevices => "cross-device link or rename",
411             Deadlock => "deadlock",
412             DirectoryNotEmpty => "directory not empty",
413             ExecutableFileBusy => "executable file busy",
414             FileTooLarge => "file too large",
415             FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
416             FilesystemQuotaExceeded => "filesystem quota exceeded",
417             HostUnreachable => "host unreachable",
418             Interrupted => "operation interrupted",
419             InvalidData => "invalid data",
420             InvalidFilename => "invalid filename",
421             InvalidInput => "invalid input parameter",
422             IsADirectory => "is a directory",
423             NetworkDown => "network down",
424             NetworkUnreachable => "network unreachable",
425             NotADirectory => "not a directory",
426             NotConnected => "not connected",
427             NotFound => "entity not found",
428             NotSeekable => "seek on unseekable file",
429             Other => "other error",
430             OutOfMemory => "out of memory",
431             PermissionDenied => "permission denied",
432             ReadOnlyFilesystem => "read-only filesystem or storage medium",
433             ResourceBusy => "resource busy",
434             StaleNetworkFileHandle => "stale network file handle",
435             StorageFull => "no storage space",
436             TimedOut => "timed out",
437             TooManyLinks => "too many links",
438             Uncategorized => "uncategorized error",
439             UnexpectedEof => "unexpected end of file",
440             Unsupported => "unsupported",
441             WouldBlock => "operation would block",
442             WriteZero => "write zero",
443         }
444         // tidy-alphabetical-end
445     }
446 }
447 
448 #[stable(feature = "io_errorkind_display", since = "1.60.0")]
449 impl fmt::Display for ErrorKind {
450     /// Shows a human-readable description of the `ErrorKind`.
451     ///
452     /// This is similar to `impl Display for Error`, but doesn't require first converting to Error.
453     ///
454     /// # Examples
455     /// ```
456     /// use std::io::ErrorKind;
457     /// assert_eq!("entity not found", ErrorKind::NotFound.to_string());
458     /// ```
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result459     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
460         fmt.write_str(self.as_str())
461     }
462 }
463 
464 /// Intended for use for errors not exposed to the user, where allocating onto
465 /// the heap (for normal construction via Error::new) is too costly.
466 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
467 impl From<ErrorKind> for Error {
468     /// Converts an [`ErrorKind`] into an [`Error`].
469     ///
470     /// This conversion creates a new error with a simple representation of error kind.
471     ///
472     /// # Examples
473     ///
474     /// ```
475     /// use std::io::{Error, ErrorKind};
476     ///
477     /// let not_found = ErrorKind::NotFound;
478     /// let error = Error::from(not_found);
479     /// assert_eq!("entity not found", format!("{error}"));
480     /// ```
481     #[inline]
from(kind: ErrorKind) -> Error482     fn from(kind: ErrorKind) -> Error {
483         Error { repr: Repr::new_simple(kind) }
484     }
485 }
486 
487 impl Error {
488     /// Creates a new I/O error from a known kind of error as well as an
489     /// arbitrary error payload.
490     ///
491     /// This function is used to generically create I/O errors which do not
492     /// originate from the OS itself. The `error` argument is an arbitrary
493     /// payload which will be contained in this [`Error`].
494     ///
495     /// Note that this function allocates memory on the heap.
496     /// If no extra payload is required, use the `From` conversion from
497     /// `ErrorKind`.
498     ///
499     /// # Examples
500     ///
501     /// ```
502     /// use std::io::{Error, ErrorKind};
503     ///
504     /// // errors can be created from strings
505     /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
506     ///
507     /// // errors can also be created from other errors
508     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
509     ///
510     /// // creating an error without payload (and without memory allocation)
511     /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
512     /// ```
513     #[stable(feature = "rust1", since = "1.0.0")]
new<E>(kind: ErrorKind, error: E) -> Error where E: Into<Box<dyn error::Error + Send + Sync>>,514     pub fn new<E>(kind: ErrorKind, error: E) -> Error
515     where
516         E: Into<Box<dyn error::Error + Send + Sync>>,
517     {
518         Self::_new(kind, error.into())
519     }
520 
521     /// Creates a new I/O error from an arbitrary error payload.
522     ///
523     /// This function is used to generically create I/O errors which do not
524     /// originate from the OS itself. It is a shortcut for [`Error::new`]
525     /// with [`ErrorKind::Other`].
526     ///
527     /// # Examples
528     ///
529     /// ```
530     /// #![feature(io_error_other)]
531     ///
532     /// use std::io::Error;
533     ///
534     /// // errors can be created from strings
535     /// let custom_error = Error::other("oh no!");
536     ///
537     /// // errors can also be created from other errors
538     /// let custom_error2 = Error::other(custom_error);
539     /// ```
540     #[unstable(feature = "io_error_other", issue = "91946")]
other<E>(error: E) -> Error where E: Into<Box<dyn error::Error + Send + Sync>>,541     pub fn other<E>(error: E) -> Error
542     where
543         E: Into<Box<dyn error::Error + Send + Sync>>,
544     {
545         Self::_new(ErrorKind::Other, error.into())
546     }
547 
_new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error548     fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
549         Error { repr: Repr::new_custom(Box::new(Custom { kind, error })) }
550     }
551 
552     /// Creates a new I/O error from a known kind of error as well as a constant
553     /// message.
554     ///
555     /// This function does not allocate.
556     ///
557     /// You should not use this directly, and instead use the `const_io_error!`
558     /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`.
559     ///
560     /// This function should maybe change to `from_static_message<const MSG: &'static
561     /// str>(kind: ErrorKind)` in the future, when const generics allow that.
562     #[inline]
from_static_message(msg: &'static SimpleMessage) -> Error563     pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error {
564         Self { repr: Repr::new_simple_message(msg) }
565     }
566 
567     /// Returns an error representing the last OS error which occurred.
568     ///
569     /// This function reads the value of `errno` for the target platform (e.g.
570     /// `GetLastError` on Windows) and will return a corresponding instance of
571     /// [`Error`] for the error code.
572     ///
573     /// This should be called immediately after a call to a platform function,
574     /// otherwise the state of the error value is indeterminate. In particular,
575     /// other standard library functions may call platform functions that may
576     /// (or may not) reset the error value even if they succeed.
577     ///
578     /// # Examples
579     ///
580     /// ```
581     /// use std::io::Error;
582     ///
583     /// let os_error = Error::last_os_error();
584     /// println!("last OS error: {os_error:?}");
585     /// ```
586     #[stable(feature = "rust1", since = "1.0.0")]
587     #[doc(alias = "GetLastError")]
588     #[doc(alias = "errno")]
589     #[must_use]
590     #[inline]
last_os_error() -> Error591     pub fn last_os_error() -> Error {
592         Error::from_raw_os_error(sys::os::errno())
593     }
594 
595     /// Creates a new instance of an [`Error`] from a particular OS error code.
596     ///
597     /// # Examples
598     ///
599     /// On Linux:
600     ///
601     /// ```
602     /// # if cfg!(target_os = "linux") {
603     /// use std::io;
604     ///
605     /// let error = io::Error::from_raw_os_error(22);
606     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
607     /// # }
608     /// ```
609     ///
610     /// On Windows:
611     ///
612     /// ```
613     /// # if cfg!(windows) {
614     /// use std::io;
615     ///
616     /// let error = io::Error::from_raw_os_error(10022);
617     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
618     /// # }
619     /// ```
620     #[stable(feature = "rust1", since = "1.0.0")]
621     #[must_use]
622     #[inline]
from_raw_os_error(code: RawOsError) -> Error623     pub fn from_raw_os_error(code: RawOsError) -> Error {
624         Error { repr: Repr::new_os(code) }
625     }
626 
627     /// Returns the OS error that this error represents (if any).
628     ///
629     /// If this [`Error`] was constructed via [`last_os_error`] or
630     /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
631     /// it will return [`None`].
632     ///
633     /// [`last_os_error`]: Error::last_os_error
634     /// [`from_raw_os_error`]: Error::from_raw_os_error
635     ///
636     /// # Examples
637     ///
638     /// ```
639     /// use std::io::{Error, ErrorKind};
640     ///
641     /// fn print_os_error(err: &Error) {
642     ///     if let Some(raw_os_err) = err.raw_os_error() {
643     ///         println!("raw OS error: {raw_os_err:?}");
644     ///     } else {
645     ///         println!("Not an OS error");
646     ///     }
647     /// }
648     ///
649     /// fn main() {
650     ///     // Will print "raw OS error: ...".
651     ///     print_os_error(&Error::last_os_error());
652     ///     // Will print "Not an OS error".
653     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
654     /// }
655     /// ```
656     #[stable(feature = "rust1", since = "1.0.0")]
657     #[must_use]
658     #[inline]
raw_os_error(&self) -> Option<RawOsError>659     pub fn raw_os_error(&self) -> Option<RawOsError> {
660         match self.repr.data() {
661             ErrorData::Os(i) => Some(i),
662             ErrorData::Custom(..) => None,
663             ErrorData::Simple(..) => None,
664             ErrorData::SimpleMessage(..) => None,
665         }
666     }
667 
668     /// Returns a reference to the inner error wrapped by this error (if any).
669     ///
670     /// If this [`Error`] was constructed via [`new`] then this function will
671     /// return [`Some`], otherwise it will return [`None`].
672     ///
673     /// [`new`]: Error::new
674     ///
675     /// # Examples
676     ///
677     /// ```
678     /// use std::io::{Error, ErrorKind};
679     ///
680     /// fn print_error(err: &Error) {
681     ///     if let Some(inner_err) = err.get_ref() {
682     ///         println!("Inner error: {inner_err:?}");
683     ///     } else {
684     ///         println!("No inner error");
685     ///     }
686     /// }
687     ///
688     /// fn main() {
689     ///     // Will print "No inner error".
690     ///     print_error(&Error::last_os_error());
691     ///     // Will print "Inner error: ...".
692     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
693     /// }
694     /// ```
695     #[stable(feature = "io_error_inner", since = "1.3.0")]
696     #[must_use]
697     #[inline]
get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)>698     pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
699         match self.repr.data() {
700             ErrorData::Os(..) => None,
701             ErrorData::Simple(..) => None,
702             ErrorData::SimpleMessage(..) => None,
703             ErrorData::Custom(c) => Some(&*c.error),
704         }
705     }
706 
707     /// Returns a mutable reference to the inner error wrapped by this error
708     /// (if any).
709     ///
710     /// If this [`Error`] was constructed via [`new`] then this function will
711     /// return [`Some`], otherwise it will return [`None`].
712     ///
713     /// [`new`]: Error::new
714     ///
715     /// # Examples
716     ///
717     /// ```
718     /// use std::io::{Error, ErrorKind};
719     /// use std::{error, fmt};
720     /// use std::fmt::Display;
721     ///
722     /// #[derive(Debug)]
723     /// struct MyError {
724     ///     v: String,
725     /// }
726     ///
727     /// impl MyError {
728     ///     fn new() -> MyError {
729     ///         MyError {
730     ///             v: "oh no!".to_string()
731     ///         }
732     ///     }
733     ///
734     ///     fn change_message(&mut self, new_message: &str) {
735     ///         self.v = new_message.to_string();
736     ///     }
737     /// }
738     ///
739     /// impl error::Error for MyError {}
740     ///
741     /// impl Display for MyError {
742     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743     ///         write!(f, "MyError: {}", &self.v)
744     ///     }
745     /// }
746     ///
747     /// fn change_error(mut err: Error) -> Error {
748     ///     if let Some(inner_err) = err.get_mut() {
749     ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
750     ///     }
751     ///     err
752     /// }
753     ///
754     /// fn print_error(err: &Error) {
755     ///     if let Some(inner_err) = err.get_ref() {
756     ///         println!("Inner error: {inner_err}");
757     ///     } else {
758     ///         println!("No inner error");
759     ///     }
760     /// }
761     ///
762     /// fn main() {
763     ///     // Will print "No inner error".
764     ///     print_error(&change_error(Error::last_os_error()));
765     ///     // Will print "Inner error: ...".
766     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
767     /// }
768     /// ```
769     #[stable(feature = "io_error_inner", since = "1.3.0")]
770     #[must_use]
771     #[inline]
get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)>772     pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
773         match self.repr.data_mut() {
774             ErrorData::Os(..) => None,
775             ErrorData::Simple(..) => None,
776             ErrorData::SimpleMessage(..) => None,
777             ErrorData::Custom(c) => Some(&mut *c.error),
778         }
779     }
780 
781     /// Consumes the `Error`, returning its inner error (if any).
782     ///
783     /// If this [`Error`] was constructed via [`new`] then this function will
784     /// return [`Some`], otherwise it will return [`None`].
785     ///
786     /// [`new`]: Error::new
787     ///
788     /// # Examples
789     ///
790     /// ```
791     /// use std::io::{Error, ErrorKind};
792     ///
793     /// fn print_error(err: Error) {
794     ///     if let Some(inner_err) = err.into_inner() {
795     ///         println!("Inner error: {inner_err}");
796     ///     } else {
797     ///         println!("No inner error");
798     ///     }
799     /// }
800     ///
801     /// fn main() {
802     ///     // Will print "No inner error".
803     ///     print_error(Error::last_os_error());
804     ///     // Will print "Inner error: ...".
805     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
806     /// }
807     /// ```
808     #[stable(feature = "io_error_inner", since = "1.3.0")]
809     #[must_use = "`self` will be dropped if the result is not used"]
810     #[inline]
into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>>811     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
812         match self.repr.into_data() {
813             ErrorData::Os(..) => None,
814             ErrorData::Simple(..) => None,
815             ErrorData::SimpleMessage(..) => None,
816             ErrorData::Custom(c) => Some(c.error),
817         }
818     }
819 
820     /// Attempt to downgrade the inner error to `E` if any.
821     ///
822     /// If this [`Error`] was constructed via [`new`] then this function will
823     /// attempt to perform downgrade on it, otherwise it will return [`Err`].
824     ///
825     /// If downgrade succeeds, it will return [`Ok`], otherwise it will also
826     /// return [`Err`].
827     ///
828     /// [`new`]: Error::new
829     ///
830     /// # Examples
831     ///
832     /// ```
833     /// #![feature(io_error_downcast)]
834     ///
835     /// use std::fmt;
836     /// use std::io;
837     /// use std::error::Error;
838     ///
839     /// #[derive(Debug)]
840     /// enum E {
841     ///     Io(io::Error),
842     ///     SomeOtherVariant,
843     /// }
844     ///
845     /// impl fmt::Display for E {
846     ///    // ...
847     /// #    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
848     /// #        todo!()
849     /// #    }
850     /// }
851     /// impl Error for E {}
852     ///
853     /// impl From<io::Error> for E {
854     ///     fn from(err: io::Error) -> E {
855     ///         err.downcast::<E>()
856     ///             .map(|b| *b)
857     ///             .unwrap_or_else(E::Io)
858     ///     }
859     /// }
860     /// ```
861     #[unstable(feature = "io_error_downcast", issue = "99262")]
downcast<E>(self) -> result::Result<Box<E>, Self> where E: error::Error + Send + Sync + 'static,862     pub fn downcast<E>(self) -> result::Result<Box<E>, Self>
863     where
864         E: error::Error + Send + Sync + 'static,
865     {
866         match self.repr.into_data() {
867             ErrorData::Custom(b) if b.error.is::<E>() => {
868                 let res = (*b).error.downcast::<E>();
869 
870                 // downcast is a really trivial and is marked as inline, so
871                 // it's likely be inlined here.
872                 //
873                 // And the compiler should be able to eliminate the branch
874                 // that produces `Err` here since b.error.is::<E>()
875                 // returns true.
876                 Ok(res.unwrap())
877             }
878             repr_data => Err(Self { repr: Repr::new(repr_data) }),
879         }
880     }
881 
882     /// Returns the corresponding [`ErrorKind`] for this error.
883     ///
884     /// This may be a value set by Rust code constructing custom `io::Error`s,
885     /// or if this `io::Error` was sourced from the operating system,
886     /// it will be a value inferred from the system's error encoding.
887     /// See [`last_os_error`] for more details.
888     ///
889     /// [`last_os_error`]: Error::last_os_error
890     ///
891     /// # Examples
892     ///
893     /// ```
894     /// use std::io::{Error, ErrorKind};
895     ///
896     /// fn print_error(err: Error) {
897     ///     println!("{:?}", err.kind());
898     /// }
899     ///
900     /// fn main() {
901     ///     // As no error has (visibly) occurred, this may print anything!
902     ///     // It likely prints a placeholder for unidentified (non-)errors.
903     ///     print_error(Error::last_os_error());
904     ///     // Will print "AddrInUse".
905     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
906     /// }
907     /// ```
908     #[stable(feature = "rust1", since = "1.0.0")]
909     #[must_use]
910     #[inline]
kind(&self) -> ErrorKind911     pub fn kind(&self) -> ErrorKind {
912         match self.repr.data() {
913             ErrorData::Os(code) => sys::decode_error_kind(code),
914             ErrorData::Custom(c) => c.kind,
915             ErrorData::Simple(kind) => kind,
916             ErrorData::SimpleMessage(m) => m.kind,
917         }
918     }
919 }
920 
921 impl fmt::Debug for Repr {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result922     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
923         match self.data() {
924             ErrorData::Os(code) => fmt
925                 .debug_struct("Os")
926                 .field("code", &code)
927                 .field("kind", &sys::decode_error_kind(code))
928                 .field("message", &sys::os::error_string(code))
929                 .finish(),
930             ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
931             ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
932             ErrorData::SimpleMessage(msg) => fmt
933                 .debug_struct("Error")
934                 .field("kind", &msg.kind)
935                 .field("message", &msg.message)
936                 .finish(),
937         }
938     }
939 }
940 
941 #[stable(feature = "rust1", since = "1.0.0")]
942 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result943     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
944         match self.repr.data() {
945             ErrorData::Os(code) => {
946                 let detail = sys::os::error_string(code);
947                 write!(fmt, "{detail} (os error {code})")
948             }
949             ErrorData::Custom(ref c) => c.error.fmt(fmt),
950             ErrorData::Simple(kind) => write!(fmt, "{}", kind.as_str()),
951             ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
952         }
953     }
954 }
955 
956 #[stable(feature = "rust1", since = "1.0.0")]
957 impl error::Error for Error {
958     #[allow(deprecated, deprecated_in_future)]
description(&self) -> &str959     fn description(&self) -> &str {
960         match self.repr.data() {
961             ErrorData::Os(..) | ErrorData::Simple(..) => self.kind().as_str(),
962             ErrorData::SimpleMessage(msg) => msg.message,
963             ErrorData::Custom(c) => c.error.description(),
964         }
965     }
966 
967     #[allow(deprecated)]
cause(&self) -> Option<&dyn error::Error>968     fn cause(&self) -> Option<&dyn error::Error> {
969         match self.repr.data() {
970             ErrorData::Os(..) => None,
971             ErrorData::Simple(..) => None,
972             ErrorData::SimpleMessage(..) => None,
973             ErrorData::Custom(c) => c.error.cause(),
974         }
975     }
976 
source(&self) -> Option<&(dyn error::Error + 'static)>977     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
978         match self.repr.data() {
979             ErrorData::Os(..) => None,
980             ErrorData::Simple(..) => None,
981             ErrorData::SimpleMessage(..) => None,
982             ErrorData::Custom(c) => c.error.source(),
983         }
984     }
985 }
986 
_assert_error_is_sync_send()987 fn _assert_error_is_sync_send() {
988     fn _is_sync_send<T: Sync + Send>() {}
989     _is_sync_send::<Error>();
990 }
991