std/io/
error.rs

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