Skip to main content

core/io/
error.rs

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