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