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