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::{error, fmt, result};
33
34/// A specialized [`Result`] type for I/O operations.
35///
36/// This type is broadly used across [`std::io`] for any operation which may
37/// produce an error.
38///
39/// This type alias is generally used to avoid writing out [`io::Error`] directly and
40/// is otherwise a direct mapping to [`Result`].
41///
42/// While usual Rust style is to import types directly, aliases of [`Result`]
43/// often are not, to make it easier to distinguish between them. [`Result`] is
44/// generally assumed to be [`core::result::Result`][`Result`], and so users of this alias
45/// will generally use `io::Result` instead of shadowing the [prelude]'s import
46/// of [`core::result::Result`][`Result`].
47///
48// FIXME(#74481): Hard-links required to link from `core` to `std`
49/// [`std::io`]: ../../std/io/index.html
50/// [`io::Error`]: Error
51/// [`Result`]: crate::result::Result
52/// [prelude]: crate::prelude
53///
54/// # Examples
55///
56/// A convenience function that bubbles an `io::Result` to its caller:
57///
58/// ```
59/// use std::io;
60///
61/// fn get_string() -> io::Result<String> {
62///     let mut buffer = String::new();
63///
64///     io::stdin().read_line(&mut buffer)?;
65///
66///     Ok(buffer)
67/// }
68/// ```
69#[stable(feature = "rust1", since = "1.0.0")]
70#[doc(search_unbox)]
71pub type Result<T> = result::Result<T, Error>;
72
73/// The error type for I/O operations of the [`Read`][Read], [`Write`][Write], [`Seek`][Seek], and
74/// associated traits.
75///
76/// Errors mostly originate from the underlying OS, but custom instances of
77/// `Error` can be created with crafted error messages and a particular value of
78/// [`ErrorKind`].
79///
80// FIXME(#74481): Hard-links required to link from `core` to `std`
81/// [Read]: ../../std/io/trait.Read.html
82/// [Write]: crate::io::Write
83/// [Seek]: crate::io::Seek
84#[stable(feature = "rust1", since = "1.0.0")]
85#[rustc_has_incoherent_inherent_impls]
86pub struct Error {
87    repr: Repr,
88}
89
90#[stable(feature = "rust1", since = "1.0.0")]
91impl fmt::Debug for Error {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        fmt::Debug::fmt(&self.repr, f)
94    }
95}
96
97/// Common errors constants for use in std
98#[doc(hidden)]
99impl Error {
100    #[doc(hidden)]
101    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
102    pub const INVALID_UTF8: Self =
103        const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
104
105    #[doc(hidden)]
106    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
107    pub const READ_EXACT_EOF: Self =
108        const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
109
110    #[doc(hidden)]
111    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
112    pub const UNKNOWN_THREAD_COUNT: Self = const_error!(
113        ErrorKind::NotFound,
114        "the number of hardware threads is not known for the target platform",
115    );
116
117    #[doc(hidden)]
118    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
119    pub const UNSUPPORTED_PLATFORM: Self =
120        const_error!(ErrorKind::Unsupported, "operation not supported on this platform");
121
122    #[doc(hidden)]
123    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
124    pub const WRITE_ALL_EOF: Self =
125        const_error!(ErrorKind::WriteZero, "failed to write whole buffer");
126
127    #[doc(hidden)]
128    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
129    pub const ZERO_TIMEOUT: Self =
130        const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
131
132    #[doc(hidden)]
133    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
134    pub const NO_ADDRESSES: Self =
135        const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses");
136}
137
138// Only derive debug in tests, to make sure it
139// doesn't accidentally get printed.
140#[cfg_attr(test, derive(Debug))]
141enum ErrorData<C> {
142    Os(RawOsError),
143    Simple(ErrorKind),
144    SimpleMessage(&'static SimpleMessage),
145    Custom(C),
146}
147
148// `#[repr(align(4))]` is probably redundant, it should have that value or
149// higher already. We include it just because repr_bitpacked.rs's encoding
150// requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
151// alignment required by the struct, only increase it).
152//
153// If we add more variants to ErrorData, this can be increased to 8, but it
154// should probably be behind `#[cfg_attr(target_pointer_width = "64", ...)]` or
155// whatever cfg we're using to enable the `repr_bitpacked` code, since only the
156// that version needs the alignment, and 8 is higher than the alignment we'll
157// have on 32 bit platforms.
158//
159// (For the sake of being explicit: the alignment requirement here only matters
160// if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't
161// matter at all)
162#[doc(hidden)]
163#[unstable(feature = "io_const_error_internals", issue = "none")]
164#[repr(align(4))]
165#[derive(Debug)]
166pub struct SimpleMessage {
167    pub kind: ErrorKind,
168    pub message: &'static str,
169}
170
171/// Creates a new I/O error from a known kind of error and a string literal.
172///
173/// Contrary to [`Error::new`][new], this macro does not allocate and can be used in
174/// `const` contexts.
175///
176// FIXME(#74481): Hard-links required to link from `core` to `alloc` for incoherent method
177/// [new]: ../../alloc/io/struct.Error.html#method.new
178///
179/// # Example
180/// ```
181/// #![feature(io_const_error)]
182/// use std::io::{const_error, Error, ErrorKind};
183///
184/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works");
185///
186/// fn not_here() -> Result<(), Error> {
187///     Err(FAIL)
188/// }
189/// ```
190#[rustc_macro_transparency = "semiopaque"]
191#[unstable(feature = "io_const_error", issue = "133448")]
192#[allow_internal_unstable(core_io, hint_must_use, io_const_error_internals)]
193pub macro const_error($kind:expr, $message:expr $(,)?) {
194    $crate::hint::must_use($crate::io::Error::from_static_message(
195        const { &$crate::io::SimpleMessage { kind: $kind, message: $message } },
196    ))
197}
198
199/// Intended for use for errors not exposed to the user, where allocating onto
200/// the heap (for normal construction via Error::new) is too costly.
201#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
202impl From<ErrorKind> for Error {
203    /// Converts an [`ErrorKind`] into an [`Error`].
204    ///
205    /// This conversion creates a new error with a simple representation of error kind.
206    ///
207    /// # Examples
208    ///
209    /// ```
210    /// use std::io::{Error, ErrorKind};
211    ///
212    /// let not_found = ErrorKind::NotFound;
213    /// let error = Error::from(not_found);
214    /// assert_eq!("entity not found", format!("{error}"));
215    /// ```
216    #[inline]
217    fn from(kind: ErrorKind) -> Error {
218        Error { repr: Repr::new_simple(kind) }
219    }
220}
221
222impl Error {
223    /// # Safety
224    ///
225    /// The provided `CustomOwner` must have been constructed from a `Box` from the `alloc` crate.
226    #[doc(hidden)]
227    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
228    #[must_use]
229    #[inline]
230    pub unsafe fn from_custom_owner(custom: CustomOwner) -> Error {
231        Error { repr: Repr::new_custom(custom) }
232    }
233
234    #[doc(hidden)]
235    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
236    #[must_use]
237    #[inline]
238    pub fn into_custom_owner(self) -> result::Result<CustomOwner, Self> {
239        if 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                        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                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(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// As with `SimpleMessage`: `#[repr(align(4))]` here is just because
579// repr_bitpacked's encoding requires it. In practice it almost certainly be
580// already be this high or higher.
581#[doc(hidden)]
582#[repr(align(4))]
583#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
584pub struct Custom {
585    kind: ErrorKind,
586    error: crate::ptr::NonNull<dyn error::Error + Send + Sync>,
587    error_drop: unsafe fn(*mut (dyn error::Error + Send + Sync)),
588    outer_drop: unsafe fn(*mut Self),
589}
590
591// SAFETY: All members of `Custom` are `Send`
592#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
593unsafe impl Send for Custom {}
594
595// SAFETY: All members of `Custom` are `Sync`
596#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
597unsafe impl Sync for Custom {}
598
599#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
600impl fmt::Debug for Custom {
601    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602        f.debug_struct("Custom").field("kind", &self.kind).field("error", self.error_ref()).finish()
603    }
604}
605
606#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
607impl Drop for Custom {
608    fn drop(&mut self) {
609        // SAFETY: `Custom::from_raw` ensures this call is safe.
610        unsafe {
611            (self.error_drop)(self.error.as_ptr());
612        }
613    }
614}
615
616impl Custom {
617    /// # Safety
618    ///
619    /// * `error` must be valid for up to a static lifetime, and own its pointee.
620    /// * `error_drop` must be safe to call for the pointer `error` exactly once.
621    /// * `outer_drop` must be safe to call on a pointer to this instance of `Custom`
622    ///   if it were stored within a [`CustomOwner`].
623    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
624    pub unsafe fn from_raw(
625        kind: ErrorKind,
626        error: crate::ptr::NonNull<dyn error::Error + Send + Sync>,
627        error_drop: unsafe fn(*mut (dyn error::Error + Send + Sync)),
628        outer_drop: unsafe fn(*mut Self),
629    ) -> Custom {
630        Custom { kind, error, error_drop, outer_drop }
631    }
632
633    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
634    pub fn into_raw(self) -> crate::ptr::NonNull<dyn error::Error + Send + Sync> {
635        let ptr = self.error;
636        core::mem::forget(self);
637        ptr
638    }
639
640    fn error_ref(&self) -> &(dyn error::Error + Send + Sync + 'static) {
641        // SAFETY:
642        // `from_raw` ensures `error` is a valid pointer up to a static lifetime
643        // and is owned by `self`
644        unsafe { self.error.as_ref() }
645    }
646
647    fn error_mut(&mut self) -> &mut (dyn error::Error + Send + Sync + 'static) {
648        // SAFETY:
649        // `from_raw` ensures `error` is a valid pointer up to a static lifetime
650        // and is owned by `self`
651        unsafe { self.error.as_mut() }
652    }
653}
654
655#[derive(Debug)]
656#[repr(transparent)]
657#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
658#[doc(hidden)]
659pub struct CustomOwner(crate::ptr::NonNull<Custom>);
660
661// SAFETY: Custom is `Send`
662#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
663unsafe impl Send for CustomOwner {}
664
665// SAFETY: Custom is `Sync`
666#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
667unsafe impl Sync for CustomOwner {}
668
669#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
670impl Drop for CustomOwner {
671    fn drop(&mut self) {
672        // SAFETY: `CustomOwner::from_raw` ensures this call is safe.
673        unsafe {
674            (self.0.as_ref().outer_drop)(self.0.as_ptr());
675        }
676    }
677}
678
679impl CustomOwner {
680    /// # Safety
681    ///
682    /// * The `outer_drop` of the provided `custom` must be safe to call exactly once.
683    #[doc(hidden)]
684    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
685    pub unsafe fn from_raw(custom: crate::ptr::NonNull<Custom>) -> CustomOwner {
686        CustomOwner(custom)
687    }
688
689    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
690    pub fn into_raw(self) -> crate::ptr::NonNull<Custom> {
691        let ptr = self.0;
692        core::mem::forget(self);
693        ptr
694    }
695
696    #[allow(dead_code, reason = "only used for unpacked representation")]
697    fn custom_ref(&self) -> &Custom {
698        // SAFETY:
699        // `from_raw` ensures `0` is a valid pointer up to a static lifetime
700        // and is owned by `self`
701        unsafe { self.0.as_ref() }
702    }
703
704    #[allow(dead_code, reason = "only used for unpacked representation")]
705    fn custom_mut(&mut self) -> &mut Custom {
706        // SAFETY:
707        // `from_raw` ensures `0` is a valid pointer up to a static lifetime
708        // and is owned by `self`
709        unsafe { self.0.as_mut() }
710    }
711}
712
713/// The type of raw OS error codes.
714///
715/// This is an [`i32`] on all currently supported platforms, but platforms
716/// added in the future (such as UEFI) may use a different primitive type like
717/// [`usize`] or [`i16`]. Use `as` or [`into`] conversions where applicable to
718/// ensure maximum portability.
719///
720/// [`into`]: Into::into
721#[unstable(feature = "raw_os_error_ty", issue = "107792")]
722pub type RawOsError = cfg_select! {
723    target_os = "uefi" => usize,
724    // For 16-bit AVR and MSP430, i16 is equivalent to c_int.
725    // Using i16 to be explicit.
726    target_pointer_width = "16" => i16,
727    _ => i32,
728};
729
730/// A list specifying general categories of I/O error.
731///
732/// This list is intended to grow over time and it is not recommended to
733/// exhaustively match against it.
734///
735/// It is used with the [`io::Error`][error] type.
736///
737/// [error]: Error
738///
739/// # Handling errors and matching on `ErrorKind`
740///
741/// In application code, use `match` for the `ErrorKind` values you are
742/// expecting; use `_` to match "all other errors".
743///
744/// In comprehensive and thorough tests that want to verify that a test doesn't
745/// return any known incorrect error kind, you may want to cut-and-paste the
746/// current full list of errors from here into your test code, and then match
747/// `_` as the correct case. This seems counterintuitive, but it will make your
748/// tests more robust. In particular, if you want to verify that your code does
749/// produce an unrecognized error kind, the robust solution is to check for all
750/// the recognized error kinds and fail in those cases.
751#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
752#[stable(feature = "rust1", since = "1.0.0")]
753#[cfg_attr(not(test), rustc_diagnostic_item = "io_errorkind")]
754#[allow(deprecated)]
755#[non_exhaustive]
756pub enum ErrorKind {
757    /// An entity was not found, often a file.
758    #[stable(feature = "rust1", since = "1.0.0")]
759    NotFound,
760    /// The operation lacked the necessary privileges to complete.
761    #[stable(feature = "rust1", since = "1.0.0")]
762    PermissionDenied,
763    /// The connection was refused by the remote server.
764    #[stable(feature = "rust1", since = "1.0.0")]
765    ConnectionRefused,
766    /// The connection was reset by the remote server.
767    #[stable(feature = "rust1", since = "1.0.0")]
768    ConnectionReset,
769    /// The remote host is not reachable.
770    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
771    HostUnreachable,
772    /// The network containing the remote host is not reachable.
773    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
774    NetworkUnreachable,
775    /// The connection was aborted (terminated) by the remote server.
776    #[stable(feature = "rust1", since = "1.0.0")]
777    ConnectionAborted,
778    /// The network operation failed because it was not connected yet.
779    #[stable(feature = "rust1", since = "1.0.0")]
780    NotConnected,
781    /// A socket address could not be bound because the address is already in
782    /// use elsewhere.
783    #[stable(feature = "rust1", since = "1.0.0")]
784    AddrInUse,
785    /// A nonexistent interface was requested or the requested address was not
786    /// local.
787    #[stable(feature = "rust1", since = "1.0.0")]
788    AddrNotAvailable,
789    /// The system's networking is down.
790    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
791    NetworkDown,
792    /// The operation failed because a pipe was closed.
793    #[stable(feature = "rust1", since = "1.0.0")]
794    BrokenPipe,
795    /// An entity already exists, often a file.
796    #[stable(feature = "rust1", since = "1.0.0")]
797    AlreadyExists,
798    /// The operation needs to block to complete, but the blocking operation was
799    /// requested to not occur.
800    #[stable(feature = "rust1", since = "1.0.0")]
801    WouldBlock,
802    /// A filesystem object is, unexpectedly, not a directory.
803    ///
804    /// For example, a filesystem path was specified where one of the intermediate directory
805    /// components was, in fact, a plain file.
806    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
807    NotADirectory,
808    /// The filesystem object is, unexpectedly, a directory.
809    ///
810    /// A directory was specified when a non-directory was expected.
811    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
812    IsADirectory,
813    /// A non-empty directory was specified where an empty directory was expected.
814    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
815    DirectoryNotEmpty,
816    /// The filesystem or storage medium is read-only, but a write operation was attempted.
817    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
818    ReadOnlyFilesystem,
819    /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
820    ///
821    /// There was a loop (or excessively long chain) resolving a filesystem object
822    /// or file IO object.
823    ///
824    /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
825    /// system-specific limit on the depth of symlink traversal.
826    #[unstable(feature = "io_error_more", issue = "86442")]
827    FilesystemLoop,
828    /// Stale network file handle.
829    ///
830    /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
831    /// by problems with the network or server.
832    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
833    StaleNetworkFileHandle,
834    /// A parameter was incorrect.
835    #[stable(feature = "rust1", since = "1.0.0")]
836    InvalidInput,
837    /// Data not valid for the operation were encountered.
838    ///
839    /// Unlike [`InvalidInput`], this typically means that the operation
840    /// parameters were valid, however the error was caused by malformed
841    /// input data.
842    ///
843    /// For example, a function that reads a file into a string will error with
844    /// `InvalidData` if the file's contents are not valid UTF-8.
845    ///
846    /// [`InvalidInput`]: ErrorKind::InvalidInput
847    #[stable(feature = "io_invalid_data", since = "1.2.0")]
848    InvalidData,
849    /// The I/O operation's timeout expired, causing it to be canceled.
850    #[stable(feature = "rust1", since = "1.0.0")]
851    TimedOut,
852    /// An error returned when an operation could not be completed because a
853    /// call to [`write`][write] returned [`Ok(0)`].
854    ///
855    /// This typically means that an operation could only succeed if it wrote a
856    /// particular number of bytes but only a smaller number of bytes could be
857    /// written.
858    ///
859    /// [write]: crate::io::Write::write
860    /// [`Ok(0)`]: Ok
861    #[stable(feature = "rust1", since = "1.0.0")]
862    WriteZero,
863    /// The underlying storage (typically, a filesystem) is full.
864    ///
865    /// This does not include out of quota errors.
866    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
867    StorageFull,
868    /// Seek on unseekable file.
869    ///
870    /// Seeking was attempted on an open file handle which is not suitable for seeking - for
871    /// example, on Unix, a named pipe opened with `File::open`.
872    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
873    NotSeekable,
874    /// Filesystem quota or some other kind of quota was exceeded.
875    #[stable(feature = "io_error_quota_exceeded", since = "1.85.0")]
876    QuotaExceeded,
877    /// File larger than allowed or supported.
878    ///
879    /// This might arise from a hard limit of the underlying filesystem or file access API, or from
880    /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
881    /// their own errors.
882    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
883    FileTooLarge,
884    /// Resource is busy.
885    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
886    ResourceBusy,
887    /// Executable file is busy.
888    ///
889    /// An attempt was made to write to a file which is also in use as a running program.  (Not all
890    /// operating systems detect this situation.)
891    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
892    ExecutableFileBusy,
893    /// Deadlock (avoided).
894    ///
895    /// A file locking operation would result in deadlock.  This situation is typically detected, if
896    /// at all, on a best-effort basis.
897    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
898    Deadlock,
899    /// Cross-device or cross-filesystem (hard) link or rename.
900    #[stable(feature = "io_error_crosses_devices", since = "1.85.0")]
901    CrossesDevices,
902    /// Too many (hard) links to the same filesystem object.
903    ///
904    /// The filesystem does not support making so many hardlinks to the same file.
905    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
906    TooManyLinks,
907    /// A filename was invalid.
908    ///
909    /// This error can also occur if a length limit for a name was exceeded.
910    #[stable(feature = "io_error_invalid_filename", since = "1.87.0")]
911    InvalidFilename,
912    /// Program argument list too long.
913    ///
914    /// When trying to run an external program, a system or process limit on the size of the
915    /// arguments would have been exceeded.
916    #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
917    ArgumentListTooLong,
918    /// This operation was interrupted.
919    ///
920    /// Interrupted operations can typically be retried.
921    #[stable(feature = "rust1", since = "1.0.0")]
922    Interrupted,
923
924    /// This operation is unsupported on this platform.
925    ///
926    /// This means that the operation can never succeed.
927    #[stable(feature = "unsupported_error", since = "1.53.0")]
928    Unsupported,
929
930    // ErrorKinds which are primarily categorisations for OS error
931    // codes should be added above.
932    //
933    /// An error returned when an operation could not be completed because an
934    /// "end of file" was reached prematurely.
935    ///
936    /// This typically means that an operation could only succeed if it read a
937    /// particular number of bytes but only a smaller number of bytes could be
938    /// read.
939    #[stable(feature = "read_exact", since = "1.6.0")]
940    UnexpectedEof,
941
942    /// An operation could not be completed, because it failed
943    /// to allocate enough memory.
944    #[stable(feature = "out_of_memory_error", since = "1.54.0")]
945    OutOfMemory,
946
947    /// The operation was partially successful and needs to be checked
948    /// later on due to not blocking.
949    #[unstable(feature = "io_error_inprogress", issue = "130840")]
950    InProgress,
951
952    /// The process or the whole system has reached its limit on the number of
953    /// open files or sockets.
954    #[unstable(feature = "io_error_too_many_open_files", issue = "158319")]
955    TooManyOpenFiles,
956
957    /// A low-level input/output error.
958    ///
959    /// This usually indicates a hardware or device-level failure, such as a bad
960    /// disk sector or a removed device, but the operating system may also report
961    /// it for other low-level I/O conditions.
962    #[unstable(feature = "io_error_input_output_error", issue = "159066")]
963    InputOutputError,
964
965    // "Unusual" error kinds which do not correspond simply to (sets
966    // of) OS error codes, should be added just above this comment.
967    // `Other` and `Uncategorized` should remain at the end:
968    //
969    /// A custom error that does not fall under any other I/O error kind.
970    ///
971    /// This can be used to construct your own [`Error`][error]s that do not match any
972    /// [`ErrorKind`].
973    ///
974    /// This [`ErrorKind`] is not used by the standard library.
975    ///
976    /// Errors from the standard library that do not fall under any of the I/O
977    /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
978    /// New [`ErrorKind`]s might be added in the future for some of those.
979    ///
980    /// [error]: Error
981    #[stable(feature = "rust1", since = "1.0.0")]
982    Other,
983
984    /// Any I/O error from the standard library that's not part of this list.
985    ///
986    /// Errors that are `Uncategorized` now may move to a different or a new
987    /// [`ErrorKind`] variant in the future. It is not recommended to match
988    /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
989    #[unstable(feature = "io_error_uncategorized", issue = "none")]
990    #[doc(hidden)]
991    Uncategorized,
992}
993
994impl ErrorKind {
995    const fn as_str(&self) -> &'static str {
996        use ErrorKind::*;
997        match *self {
998            // tidy-alphabetical-start
999            AddrInUse => "address in use",
1000            AddrNotAvailable => "address not available",
1001            AlreadyExists => "entity already exists",
1002            ArgumentListTooLong => "argument list too long",
1003            BrokenPipe => "broken pipe",
1004            ConnectionAborted => "connection aborted",
1005            ConnectionRefused => "connection refused",
1006            ConnectionReset => "connection reset",
1007            CrossesDevices => "cross-device link or rename",
1008            Deadlock => "deadlock",
1009            DirectoryNotEmpty => "directory not empty",
1010            ExecutableFileBusy => "executable file busy",
1011            FileTooLarge => "file too large",
1012            FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
1013            HostUnreachable => "host unreachable",
1014            InProgress => "in progress",
1015            InputOutputError => "input/output error",
1016            Interrupted => "operation interrupted",
1017            InvalidData => "invalid data",
1018            InvalidFilename => "invalid filename",
1019            InvalidInput => "invalid input parameter",
1020            IsADirectory => "is a directory",
1021            NetworkDown => "network down",
1022            NetworkUnreachable => "network unreachable",
1023            NotADirectory => "not a directory",
1024            NotConnected => "not connected",
1025            NotFound => "entity not found",
1026            NotSeekable => "seek on unseekable file",
1027            Other => "other error",
1028            OutOfMemory => "out of memory",
1029            PermissionDenied => "permission denied",
1030            QuotaExceeded => "quota exceeded",
1031            ReadOnlyFilesystem => "read-only filesystem or storage medium",
1032            ResourceBusy => "resource busy",
1033            StaleNetworkFileHandle => "stale network file handle",
1034            StorageFull => "no storage space",
1035            TimedOut => "timed out",
1036            TooManyLinks => "too many links",
1037            TooManyOpenFiles => "too many open files",
1038            Uncategorized => "uncategorized error",
1039            UnexpectedEof => "unexpected end of file",
1040            Unsupported => "unsupported",
1041            WouldBlock => "operation would block",
1042            WriteZero => "write zero",
1043            // tidy-alphabetical-end
1044        }
1045    }
1046
1047    // This compiles to the same code as the check+transmute, but doesn't require
1048    // unsafe, or to hard-code max ErrorKind or its size in a way the compiler
1049    // couldn't verify.
1050    #[inline]
1051    #[allow(dead_code, reason = "only used for packed representation")]
1052    const fn from_prim(ek: u32) -> Option<Self> {
1053        macro_rules! from_prim {
1054            ($prim:expr => $Enum:ident { $($Variant:ident),* $(,)? }) => {{
1055                // Force a compile error if the list gets out of date.
1056                const _: fn(e: $Enum) = |e: $Enum| match e {
1057                    $($Enum::$Variant => (),)*
1058                };
1059                match $prim {
1060                    $(v if v == ($Enum::$Variant as _) => Some($Enum::$Variant),)*
1061                    _ => None,
1062                }
1063            }}
1064        }
1065        from_prim!(ek => ErrorKind {
1066            NotFound,
1067            PermissionDenied,
1068            ConnectionRefused,
1069            ConnectionReset,
1070            HostUnreachable,
1071            NetworkUnreachable,
1072            ConnectionAborted,
1073            NotConnected,
1074            AddrInUse,
1075            AddrNotAvailable,
1076            NetworkDown,
1077            BrokenPipe,
1078            AlreadyExists,
1079            WouldBlock,
1080            NotADirectory,
1081            IsADirectory,
1082            DirectoryNotEmpty,
1083            ReadOnlyFilesystem,
1084            FilesystemLoop,
1085            StaleNetworkFileHandle,
1086            InvalidInput,
1087            InvalidData,
1088            TimedOut,
1089            WriteZero,
1090            StorageFull,
1091            NotSeekable,
1092            QuotaExceeded,
1093            FileTooLarge,
1094            ResourceBusy,
1095            ExecutableFileBusy,
1096            Deadlock,
1097            CrossesDevices,
1098            TooManyLinks,
1099            InvalidFilename,
1100            ArgumentListTooLong,
1101            Interrupted,
1102            Other,
1103            UnexpectedEof,
1104            Unsupported,
1105            OutOfMemory,
1106            InProgress,
1107            TooManyOpenFiles,
1108            InputOutputError,
1109            Uncategorized,
1110        })
1111    }
1112}
1113
1114#[stable(feature = "io_errorkind_display", since = "1.60.0")]
1115impl fmt::Display for ErrorKind {
1116    /// Shows a human-readable description of the [`ErrorKind`].
1117    ///
1118    /// This is similar to `impl Display for Error`, but doesn't require first converting to Error.
1119    ///
1120    /// # Examples
1121    ///
1122    /// ```
1123    /// use core::io::ErrorKind;
1124    /// assert_eq!("entity not found", ErrorKind::NotFound.to_string());
1125    /// ```
1126    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1127        fmt.write_str(self.as_str())
1128    }
1129}