1#![unstable(feature = "core_io", issue = "154046")]
23// 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;
1920#[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;
2930use self::os_functions::{decode_error_kind, format_os_error, is_interrupted, set_functions};
31use self::repr::Repr;
32use crate::{error, fmt, result};
3334/// 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>;
7273/// 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}
8990#[stable(feature = "rust1", since = "1.0.0")]
91impl fmt::Debugfor Error {
92fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 fmt::Debug::fmt(&self.repr, f)
94 }
95}
9697/// 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")]
102pub const INVALID_UTF8: Self =
103crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::InvalidData,
message: "stream did not contain valid UTF-8",
}
}))const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
104105#[doc(hidden)]
106 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
107pub const READ_EXACT_EOF: Self =
108crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::UnexpectedEof,
message: "failed to fill whole buffer",
}
}))const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
109110#[doc(hidden)]
111 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
112pub const UNKNOWN_THREAD_COUNT: Self = crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::NotFound,
message: "the number of hardware threads is not known for the target platform",
}
}))const_error!(
113 ErrorKind::NotFound,
114"the number of hardware threads is not known for the target platform",
115 );
116117#[doc(hidden)]
118 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
119pub const UNSUPPORTED_PLATFORM: Self =
120crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::Unsupported,
message: "operation not supported on this platform",
}
}))const_error!(ErrorKind::Unsupported, "operation not supported on this platform");
121122#[doc(hidden)]
123 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
124pub const WRITE_ALL_EOF: Self =
125crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::WriteZero,
message: "failed to write whole buffer",
}
}))const_error!(ErrorKind::WriteZero, "failed to write whole buffer");
126127#[doc(hidden)]
128 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
129pub const ZERO_TIMEOUT: Self =
130crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::InvalidInput,
message: "cannot set a 0 duration timeout",
}
}))const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
131132#[doc(hidden)]
133 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
134pub const NO_ADDRESSES: Self =
135crate::hint::must_use(crate::io::Error::from_static_message(const {
&crate::io::SimpleMessage {
kind: ErrorKind::InvalidInput,
message: "could not resolve to any addresses",
}
}))const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses");
136}
137138// 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}
147148// `#[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(#[automatically_derived]
#[unstable(feature = "io_const_error_internals", issue = "none")]
impl crate::fmt::Debug for SimpleMessage {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::debug_struct_field2_finish(f, "SimpleMessage",
"kind", &self.kind, "message", &&self.message)
}
}Debug)]
166pub struct SimpleMessage {
167pub kind: ErrorKind,
168pub message: &'static str,
169}
170171/// 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(
195const { &$crate::io::SimpleMessage { kind: $kind, message: $message } },
196 ))
197}
198199/// 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]
217fn from(kind: ErrorKind) -> Error {
218Error { repr: Repr::new_simple(kind) }
219 }
220}
221222impl 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]
230pub unsafe fn from_custom_owner(custom: CustomOwner) -> Error {
231Error { repr: Repr::new_custom(custom) }
232 }
233234#[doc(hidden)]
235 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
236 #[must_use]
237 #[inline]
238pub fn into_custom_owner(self) -> result::Result<CustomOwner, Self> {
239if #[allow(non_exhaustive_omitted_patterns)] match self.repr.data() {
ErrorData::Custom(..) => true,
_ => false,
}matches!(self.repr.data(), ErrorData::Custom(..)) {
240let ErrorData::Custom(c) = self.repr.into_data() else {
241// SAFETY: Checked above using `matches!`.
242unsafe { crate::hint::unreachable_unchecked() }
243 };
244Ok(c)
245 } else {
246Err(self)
247 }
248 }
249250/// 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")]
263pub const fn from_static_message(msg: &'static SimpleMessage) -> Error {
264Self { repr: Repr::new_simple_message(msg) }
265 }
266267/// # 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]
275pub 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.
280unsafe {
281set_functions(functions);
282 }
283Error { repr: Repr::new_os(code) }
284 }
285286/// 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]
319pub fn raw_os_error(&self) -> Option<RawOsError> {
320match self.repr.data() {
321 ErrorData::Os(i) => Some(i),
322 ErrorData::Custom(..) => None,
323 ErrorData::Simple(..) => None,
324 ErrorData::SimpleMessage(..) => None,
325 }
326 }
327328/// 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]
358pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
359match 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 }
366367/// 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]
433pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
434match 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 }
441442/// 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]
472pub fn kind(&self) -> ErrorKind {
473match 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 }
480481#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
482 #[doc(hidden)]
483 #[inline]
484pub fn is_interrupted(&self) -> bool {
485match 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}
493494impl fmt::Debugfor Repr {
495fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
496match self.data() {
497 ErrorData::Os(code) => fmt498 .debug_struct("Os")
499 .field("code", &code)
500 .field("kind", &decode_error_kind(code))
501 .field(
502"message",
503&fmt::from_fn(|fmt| {
504fmt.write_fmt(format_args!("\"{0}\"",
fmt::from_fn(|fmt| format_os_error(code, fmt))))write!(fmt, "\"{}\"", fmt::from_fn(|fmt| format_os_error(code, fmt)))505 }),
506 )
507 .finish(),
508 ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
509 ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
510 ErrorData::SimpleMessage(msg) => fmt511 .debug_struct("Error")
512 .field("kind", &msg.kind)
513 .field("message", &msg.message)
514 .finish(),
515 }
516 }
517}
518519#[stable(feature = "rust1", since = "1.0.0")]
520impl fmt::Displayfor Error {
521fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
522match self.repr.data() {
523 ErrorData::Os(code) => {
524let detail = fmt::from_fn(|fmt| format_os_error(code, fmt));
525fmt.write_fmt(format_args!("{0} (os error {1})", detail, code))write!(fmt, "{detail} (os error {code})")526 }
527 ErrorData::Custom(c) => fmt::Display::fmt(c.error_ref(), fmt),
528 ErrorData::Simple(kind) => kind.fmt(fmt),
529 ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
530 }
531 }
532}
533534#[stable(feature = "rust1", since = "1.0.0")]
535impl error::Errorfor Error {
536#[allow(deprecated)]
537fn cause(&self) -> Option<&dyn error::Error> {
538match 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 }
545546fn source(&self) -> Option<&(dyn error::Error + 'static)> {
547match 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}
555556fn _assert_error_is_sync_send() {
557fn _is_sync_send<T: Sync + Send>() {}
558_is_sync_send::<Error>();
559}
560561#[doc(hidden)]
562#[derive(#[automatically_derived]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd",
issue = "none")]
impl crate::fmt::Debug for OsFunctions {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::debug_struct_field3_finish(f, "OsFunctions",
"format_os_error", &self.format_os_error, "decode_error_kind",
&self.decode_error_kind, "is_interrupted", &&self.is_interrupted)
}
}Debug)]
563#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
564pub struct OsFunctions {
565pub format_os_error: fn(_: RawOsError, _: &mut fmt::Formatter<'_>) -> fmt::Result,
566pub decode_error_kind: fn(_: RawOsError) -> ErrorKind,
567pub is_interrupted: fn(_: RawOsError) -> bool,
568}
569570impl OsFunctions {
571const DEFAULT: &'static OsFunctions = &OsFunctions {
572 format_os_error: |_, _| Ok(()),
573 decode_error_kind: |_| ErrorKind::Uncategorized,
574 is_interrupted: |_| false,
575 };
576}
577578// 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}
590591// SAFETY: All members of `Custom` are `Send`
592#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
593unsafe impl Sendfor Custom {}
594595// SAFETY: All members of `Custom` are `Sync`
596#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
597unsafe impl Syncfor Custom {}
598599#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
600impl fmt::Debugfor Custom {
601fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602f.debug_struct("Custom").field("kind", &self.kind).field("error", self.error_ref()).finish()
603 }
604}
605606#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
607impl Dropfor Custom {
608fn drop(&mut self) {
609// SAFETY: `Custom::from_raw` ensures this call is safe.
610unsafe {
611 (self.error_drop)(self.error.as_ptr());
612 }
613 }
614}
615616impl 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")]
624pub 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 {
630Custom { kind, error, error_drop, outer_drop }
631 }
632633#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
634pub fn into_raw(self) -> crate::ptr::NonNull<dyn error::Error + Send + Sync> {
635let ptr = self.error;
636 core::mem::forget(self);
637ptr638 }
639640fn 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`
644unsafe { self.error.as_ref() }
645 }
646647fn 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`
651unsafe { self.error.as_mut() }
652 }
653}
654655#[derive(#[automatically_derived]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd",
issue = "none")]
impl crate::fmt::Debug for CustomOwner {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::debug_tuple_field1_finish(f, "CustomOwner",
&&self.0)
}
}Debug)]
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>);
660661// SAFETY: Custom is `Send`
662#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
663unsafe impl Sendfor CustomOwner {}
664665// SAFETY: Custom is `Sync`
666#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
667unsafe impl Syncfor CustomOwner {}
668669#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
670impl Dropfor CustomOwner {
671fn drop(&mut self) {
672// SAFETY: `CustomOwner::from_raw` ensures this call is safe.
673unsafe {
674 (self.0.as_ref().outer_drop)(self.0.as_ptr());
675 }
676 }
677}
678679impl 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")]
685pub unsafe fn from_raw(custom: crate::ptr::NonNull<Custom>) -> CustomOwner {
686CustomOwner(custom)
687 }
688689#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
690pub fn into_raw(self) -> crate::ptr::NonNull<Custom> {
691let ptr = self.0;
692 core::mem::forget(self);
693ptr694 }
695696#[allow(dead_code, reason = "only used for unpacked representation")]
697fn 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`
701unsafe { self.0.as_ref() }
702 }
703704#[allow(dead_code, reason = "only used for unpacked representation")]
705fn 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`
709unsafe { self.0.as_mut() }
710 }
711}
712713/// 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`]. Use `as` or [`into`] conversions where applicable to ensure maximum
718/// 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_ => i32,
725};
726727/// A list specifying general categories of I/O error.
728///
729/// This list is intended to grow over time and it is not recommended to
730/// exhaustively match against it.
731///
732/// It is used with the [`io::Error`][error] type.
733///
734/// [error]: Error
735///
736/// # Handling errors and matching on `ErrorKind`
737///
738/// In application code, use `match` for the `ErrorKind` values you are
739/// expecting; use `_` to match "all other errors".
740///
741/// In comprehensive and thorough tests that want to verify that a test doesn't
742/// return any known incorrect error kind, you may want to cut-and-paste the
743/// current full list of errors from here into your test code, and then match
744/// `_` as the correct case. This seems counterintuitive, but it will make your
745/// tests more robust. In particular, if you want to verify that your code does
746/// produce an unrecognized error kind, the robust solution is to check for all
747/// the recognized error kinds and fail in those cases.
748#[derive(#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::clone::Clone for ErrorKind {
#[inline]
fn clone(&self) -> ErrorKind { *self }
}Clone, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::marker::Copy for ErrorKind { }Copy, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::fmt::Debug for ErrorKind {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::write_str(f,
match self {
ErrorKind::NotFound => "NotFound",
ErrorKind::PermissionDenied => "PermissionDenied",
ErrorKind::ConnectionRefused => "ConnectionRefused",
ErrorKind::ConnectionReset => "ConnectionReset",
ErrorKind::HostUnreachable => "HostUnreachable",
ErrorKind::NetworkUnreachable => "NetworkUnreachable",
ErrorKind::ConnectionAborted => "ConnectionAborted",
ErrorKind::NotConnected => "NotConnected",
ErrorKind::AddrInUse => "AddrInUse",
ErrorKind::AddrNotAvailable => "AddrNotAvailable",
ErrorKind::NetworkDown => "NetworkDown",
ErrorKind::BrokenPipe => "BrokenPipe",
ErrorKind::AlreadyExists => "AlreadyExists",
ErrorKind::WouldBlock => "WouldBlock",
ErrorKind::NotADirectory => "NotADirectory",
ErrorKind::IsADirectory => "IsADirectory",
ErrorKind::DirectoryNotEmpty => "DirectoryNotEmpty",
ErrorKind::ReadOnlyFilesystem => "ReadOnlyFilesystem",
ErrorKind::FilesystemLoop => "FilesystemLoop",
ErrorKind::StaleNetworkFileHandle => "StaleNetworkFileHandle",
ErrorKind::InvalidInput => "InvalidInput",
ErrorKind::InvalidData => "InvalidData",
ErrorKind::TimedOut => "TimedOut",
ErrorKind::WriteZero => "WriteZero",
ErrorKind::StorageFull => "StorageFull",
ErrorKind::NotSeekable => "NotSeekable",
ErrorKind::QuotaExceeded => "QuotaExceeded",
ErrorKind::FileTooLarge => "FileTooLarge",
ErrorKind::ResourceBusy => "ResourceBusy",
ErrorKind::ExecutableFileBusy => "ExecutableFileBusy",
ErrorKind::Deadlock => "Deadlock",
ErrorKind::CrossesDevices => "CrossesDevices",
ErrorKind::TooManyLinks => "TooManyLinks",
ErrorKind::InvalidFilename => "InvalidFilename",
ErrorKind::ArgumentListTooLong => "ArgumentListTooLong",
ErrorKind::Interrupted => "Interrupted",
ErrorKind::Unsupported => "Unsupported",
ErrorKind::UnexpectedEof => "UnexpectedEof",
ErrorKind::OutOfMemory => "OutOfMemory",
ErrorKind::InProgress => "InProgress",
ErrorKind::TooManyOpenFiles => "TooManyOpenFiles",
ErrorKind::InputOutputError => "InputOutputError",
ErrorKind::Other => "Other",
ErrorKind::Uncategorized => "Uncategorized",
})
}
}Debug, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::cmp::Eq for ErrorKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::hash::Hash for ErrorKind {
#[inline]
fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = crate::intrinsics::discriminant_value(self);
crate::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::cmp::Ord for ErrorKind {
#[inline]
fn cmp(&self, other: &ErrorKind) -> crate::cmp::Ordering {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
crate::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::cmp::PartialEq for ErrorKind {
#[inline]
fn eq(&self, other: &ErrorKind) -> bool {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl crate::cmp::PartialOrd for ErrorKind {
#[inline]
fn partial_cmp(&self, other: &ErrorKind)
-> crate::option::Option<crate::cmp::Ordering> {
crate::option::Option::Some(crate::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
749#[stable(feature = "rust1", since = "1.0.0")]
750#[cfg_attr(not(test), rustc_diagnostic_item = "io_errorkind")]
751#[allow(deprecated)]
752#[non_exhaustive]
753pub enum ErrorKind {
754/// An entity was not found, often a file.
755#[stable(feature = "rust1", since = "1.0.0")]
756NotFound,
757/// The operation lacked the necessary privileges to complete.
758#[stable(feature = "rust1", since = "1.0.0")]
759PermissionDenied,
760/// The connection was refused by the remote server.
761#[stable(feature = "rust1", since = "1.0.0")]
762ConnectionRefused,
763/// The connection was reset by the remote server.
764#[stable(feature = "rust1", since = "1.0.0")]
765ConnectionReset,
766/// The remote host is not reachable.
767#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
768HostUnreachable,
769/// The network containing the remote host is not reachable.
770#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
771NetworkUnreachable,
772/// The connection was aborted (terminated) by the remote server.
773#[stable(feature = "rust1", since = "1.0.0")]
774ConnectionAborted,
775/// The network operation failed because it was not connected yet.
776#[stable(feature = "rust1", since = "1.0.0")]
777NotConnected,
778/// A socket address could not be bound because the address is already in
779 /// use elsewhere.
780#[stable(feature = "rust1", since = "1.0.0")]
781AddrInUse,
782/// A nonexistent interface was requested or the requested address was not
783 /// local.
784#[stable(feature = "rust1", since = "1.0.0")]
785AddrNotAvailable,
786/// The system's networking is down.
787#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
788NetworkDown,
789/// The operation failed because a pipe was closed.
790#[stable(feature = "rust1", since = "1.0.0")]
791BrokenPipe,
792/// An entity already exists, often a file.
793#[stable(feature = "rust1", since = "1.0.0")]
794AlreadyExists,
795/// The operation needs to block to complete, but the blocking operation was
796 /// requested to not occur.
797#[stable(feature = "rust1", since = "1.0.0")]
798WouldBlock,
799/// A filesystem object is, unexpectedly, not a directory.
800 ///
801 /// For example, a filesystem path was specified where one of the intermediate directory
802 /// components was, in fact, a plain file.
803#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
804NotADirectory,
805/// The filesystem object is, unexpectedly, a directory.
806 ///
807 /// A directory was specified when a non-directory was expected.
808#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
809IsADirectory,
810/// A non-empty directory was specified where an empty directory was expected.
811#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
812DirectoryNotEmpty,
813/// The filesystem or storage medium is read-only, but a write operation was attempted.
814#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
815ReadOnlyFilesystem,
816/// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
817 ///
818 /// There was a loop (or excessively long chain) resolving a filesystem object
819 /// or file IO object.
820 ///
821 /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
822 /// system-specific limit on the depth of symlink traversal.
823#[unstable(feature = "io_error_more", issue = "86442")]
824FilesystemLoop,
825/// Stale network file handle.
826 ///
827 /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
828 /// by problems with the network or server.
829#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
830StaleNetworkFileHandle,
831/// A parameter was incorrect.
832#[stable(feature = "rust1", since = "1.0.0")]
833InvalidInput,
834/// Data not valid for the operation were encountered.
835 ///
836 /// Unlike [`InvalidInput`], this typically means that the operation
837 /// parameters were valid, however the error was caused by malformed
838 /// input data.
839 ///
840 /// For example, a function that reads a file into a string will error with
841 /// `InvalidData` if the file's contents are not valid UTF-8.
842 ///
843 /// [`InvalidInput`]: ErrorKind::InvalidInput
844#[stable(feature = "io_invalid_data", since = "1.2.0")]
845InvalidData,
846/// The I/O operation's timeout expired, causing it to be canceled.
847#[stable(feature = "rust1", since = "1.0.0")]
848TimedOut,
849/// An error returned when an operation could not be completed because a
850 /// call to [`write`][write] returned [`Ok(0)`].
851 ///
852 /// This typically means that an operation could only succeed if it wrote a
853 /// particular number of bytes but only a smaller number of bytes could be
854 /// written.
855 ///
856 /// [write]: crate::io::Write::write
857 /// [`Ok(0)`]: Ok
858#[stable(feature = "rust1", since = "1.0.0")]
859WriteZero,
860/// The underlying storage (typically, a filesystem) is full.
861 ///
862 /// This does not include out of quota errors.
863#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
864StorageFull,
865/// Seek on unseekable file.
866 ///
867 /// Seeking was attempted on an open file handle which is not suitable for seeking - for
868 /// example, on Unix, a named pipe opened with `File::open`.
869#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
870NotSeekable,
871/// Filesystem quota or some other kind of quota was exceeded.
872#[stable(feature = "io_error_quota_exceeded", since = "1.85.0")]
873QuotaExceeded,
874/// File larger than allowed or supported.
875 ///
876 /// This might arise from a hard limit of the underlying filesystem or file access API, or from
877 /// an administratively imposed resource limitation. Simple disk full, and out of quota, have
878 /// their own errors.
879#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
880FileTooLarge,
881/// Resource is busy.
882#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
883ResourceBusy,
884/// Executable file is busy.
885 ///
886 /// An attempt was made to write to a file which is also in use as a running program. (Not all
887 /// operating systems detect this situation.)
888#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
889ExecutableFileBusy,
890/// Deadlock (avoided).
891 ///
892 /// A file locking operation would result in deadlock. This situation is typically detected, if
893 /// at all, on a best-effort basis.
894#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
895Deadlock,
896/// Cross-device or cross-filesystem (hard) link or rename.
897#[stable(feature = "io_error_crosses_devices", since = "1.85.0")]
898CrossesDevices,
899/// Too many (hard) links to the same filesystem object.
900 ///
901 /// The filesystem does not support making so many hardlinks to the same file.
902#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
903TooManyLinks,
904/// A filename was invalid.
905 ///
906 /// This error can also occur if a length limit for a name was exceeded.
907#[stable(feature = "io_error_invalid_filename", since = "1.87.0")]
908InvalidFilename,
909/// Program argument list too long.
910 ///
911 /// When trying to run an external program, a system or process limit on the size of the
912 /// arguments would have been exceeded.
913#[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
914ArgumentListTooLong,
915/// This operation was interrupted.
916 ///
917 /// Interrupted operations can typically be retried.
918#[stable(feature = "rust1", since = "1.0.0")]
919Interrupted,
920921/// This operation is unsupported on this platform.
922 ///
923 /// This means that the operation can never succeed.
924#[stable(feature = "unsupported_error", since = "1.53.0")]
925Unsupported,
926927// ErrorKinds which are primarily categorisations for OS error
928 // codes should be added above.
929 //
930/// An error returned when an operation could not be completed because an
931 /// "end of file" was reached prematurely.
932 ///
933 /// This typically means that an operation could only succeed if it read a
934 /// particular number of bytes but only a smaller number of bytes could be
935 /// read.
936#[stable(feature = "read_exact", since = "1.6.0")]
937UnexpectedEof,
938939/// An operation could not be completed, because it failed
940 /// to allocate enough memory.
941#[stable(feature = "out_of_memory_error", since = "1.54.0")]
942OutOfMemory,
943944/// The operation was partially successful and needs to be checked
945 /// later on due to not blocking.
946#[unstable(feature = "io_error_inprogress", issue = "130840")]
947InProgress,
948949/// The process or the whole system has reached its limit on the number of
950 /// open files or sockets.
951#[unstable(feature = "io_error_too_many_open_files", issue = "158319")]
952TooManyOpenFiles,
953954/// A low-level input/output error.
955 ///
956 /// This usually indicates a hardware or device-level failure, such as a bad
957 /// disk sector or a removed device, but the operating system may also report
958 /// it for other low-level I/O conditions.
959#[unstable(feature = "io_error_input_output_error", issue = "159066")]
960InputOutputError,
961962// "Unusual" error kinds which do not correspond simply to (sets
963 // of) OS error codes, should be added just above this comment.
964 // `Other` and `Uncategorized` should remain at the end:
965 //
966/// A custom error that does not fall under any other I/O error kind.
967 ///
968 /// This can be used to construct your own [`Error`][error]s that do not match any
969 /// [`ErrorKind`].
970 ///
971 /// This [`ErrorKind`] is not used by the standard library.
972 ///
973 /// Errors from the standard library that do not fall under any of the I/O
974 /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
975 /// New [`ErrorKind`]s might be added in the future for some of those.
976 ///
977 /// [error]: Error
978#[stable(feature = "rust1", since = "1.0.0")]
979Other,
980981/// Any I/O error from the standard library that's not part of this list.
982 ///
983 /// Errors that are `Uncategorized` now may move to a different or a new
984 /// [`ErrorKind`] variant in the future. It is not recommended to match
985 /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
986#[unstable(feature = "io_error_uncategorized", issue = "none")]
987 #[doc(hidden)]
988Uncategorized,
989}
990991impl ErrorKind {
992const fn as_str(&self) -> &'static str {
993use ErrorKind::*;
994match *self {
995// tidy-alphabetical-start
996AddrInUse => "address in use",
997AddrNotAvailable => "address not available",
998AlreadyExists => "entity already exists",
999ArgumentListTooLong => "argument list too long",
1000BrokenPipe => "broken pipe",
1001ConnectionAborted => "connection aborted",
1002ConnectionRefused => "connection refused",
1003ConnectionReset => "connection reset",
1004CrossesDevices => "cross-device link or rename",
1005Deadlock => "deadlock",
1006DirectoryNotEmpty => "directory not empty",
1007ExecutableFileBusy => "executable file busy",
1008FileTooLarge => "file too large",
1009FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
1010HostUnreachable => "host unreachable",
1011InProgress => "in progress",
1012InputOutputError => "input/output error",
1013Interrupted => "operation interrupted",
1014InvalidData => "invalid data",
1015InvalidFilename => "invalid filename",
1016InvalidInput => "invalid input parameter",
1017IsADirectory => "is a directory",
1018NetworkDown => "network down",
1019NetworkUnreachable => "network unreachable",
1020NotADirectory => "not a directory",
1021NotConnected => "not connected",
1022NotFound => "entity not found",
1023NotSeekable => "seek on unseekable file",
1024Other => "other error",
1025OutOfMemory => "out of memory",
1026PermissionDenied => "permission denied",
1027QuotaExceeded => "quota exceeded",
1028ReadOnlyFilesystem => "read-only filesystem or storage medium",
1029ResourceBusy => "resource busy",
1030StaleNetworkFileHandle => "stale network file handle",
1031StorageFull => "no storage space",
1032TimedOut => "timed out",
1033TooManyLinks => "too many links",
1034TooManyOpenFiles => "too many open files",
1035Uncategorized => "uncategorized error",
1036UnexpectedEof => "unexpected end of file",
1037Unsupported => "unsupported",
1038WouldBlock => "operation would block",
1039WriteZero => "write zero",
1040// tidy-alphabetical-end
1041}
1042 }
10431044// This compiles to the same code as the check+transmute, but doesn't require
1045 // unsafe, or to hard-code max ErrorKind or its size in a way the compiler
1046 // couldn't verify.
1047#[inline]
1048 #[allow(dead_code, reason = "only used for packed representation")]
1049const fn from_prim(ek: u32) -> Option<Self> {
1050macro_rules! from_prim {
1051 ($prim:expr => $Enum:ident { $($Variant:ident),* $(,)? }) => {{
1052// Force a compile error if the list gets out of date.
1053const _: fn(e: $Enum) = |e: $Enum| match e {
1054 $($Enum::$Variant => (),)*
1055 };
1056match $prim {
1057 $(v if v == ($Enum::$Variant as _) => Some($Enum::$Variant),)*
1058_ => None,
1059 }
1060 }}
1061 }
1062{
const _: fn(e: ErrorKind) =
|e: ErrorKind|
match e {
ErrorKind::NotFound => (),
ErrorKind::PermissionDenied => (),
ErrorKind::ConnectionRefused => (),
ErrorKind::ConnectionReset => (),
ErrorKind::HostUnreachable => (),
ErrorKind::NetworkUnreachable => (),
ErrorKind::ConnectionAborted => (),
ErrorKind::NotConnected => (),
ErrorKind::AddrInUse => (),
ErrorKind::AddrNotAvailable => (),
ErrorKind::NetworkDown => (),
ErrorKind::BrokenPipe => (),
ErrorKind::AlreadyExists => (),
ErrorKind::WouldBlock => (),
ErrorKind::NotADirectory => (),
ErrorKind::IsADirectory => (),
ErrorKind::DirectoryNotEmpty => (),
ErrorKind::ReadOnlyFilesystem => (),
ErrorKind::FilesystemLoop => (),
ErrorKind::StaleNetworkFileHandle => (),
ErrorKind::InvalidInput => (),
ErrorKind::InvalidData => (),
ErrorKind::TimedOut => (),
ErrorKind::WriteZero => (),
ErrorKind::StorageFull => (),
ErrorKind::NotSeekable => (),
ErrorKind::QuotaExceeded => (),
ErrorKind::FileTooLarge => (),
ErrorKind::ResourceBusy => (),
ErrorKind::ExecutableFileBusy => (),
ErrorKind::Deadlock => (),
ErrorKind::CrossesDevices => (),
ErrorKind::TooManyLinks => (),
ErrorKind::InvalidFilename => (),
ErrorKind::ArgumentListTooLong => (),
ErrorKind::Interrupted => (),
ErrorKind::Other => (),
ErrorKind::UnexpectedEof => (),
ErrorKind::Unsupported => (),
ErrorKind::OutOfMemory => (),
ErrorKind::InProgress => (),
ErrorKind::TooManyOpenFiles => (),
ErrorKind::InputOutputError => (),
ErrorKind::Uncategorized => (),
};
match ek {
v if v == (ErrorKind::NotFound as _) => Some(ErrorKind::NotFound),
v if v == (ErrorKind::PermissionDenied as _) =>
Some(ErrorKind::PermissionDenied),
v if v == (ErrorKind::ConnectionRefused as _) =>
Some(ErrorKind::ConnectionRefused),
v if v == (ErrorKind::ConnectionReset as _) =>
Some(ErrorKind::ConnectionReset),
v if v == (ErrorKind::HostUnreachable as _) =>
Some(ErrorKind::HostUnreachable),
v if v == (ErrorKind::NetworkUnreachable as _) =>
Some(ErrorKind::NetworkUnreachable),
v if v == (ErrorKind::ConnectionAborted as _) =>
Some(ErrorKind::ConnectionAborted),
v if v == (ErrorKind::NotConnected as _) =>
Some(ErrorKind::NotConnected),
v if v == (ErrorKind::AddrInUse as _) => Some(ErrorKind::AddrInUse),
v if v == (ErrorKind::AddrNotAvailable as _) =>
Some(ErrorKind::AddrNotAvailable),
v if v == (ErrorKind::NetworkDown as _) =>
Some(ErrorKind::NetworkDown),
v if v == (ErrorKind::BrokenPipe as _) => Some(ErrorKind::BrokenPipe),
v if v == (ErrorKind::AlreadyExists as _) =>
Some(ErrorKind::AlreadyExists),
v if v == (ErrorKind::WouldBlock as _) => Some(ErrorKind::WouldBlock),
v if v == (ErrorKind::NotADirectory as _) =>
Some(ErrorKind::NotADirectory),
v if v == (ErrorKind::IsADirectory as _) =>
Some(ErrorKind::IsADirectory),
v if v == (ErrorKind::DirectoryNotEmpty as _) =>
Some(ErrorKind::DirectoryNotEmpty),
v if v == (ErrorKind::ReadOnlyFilesystem as _) =>
Some(ErrorKind::ReadOnlyFilesystem),
v if v == (ErrorKind::FilesystemLoop as _) =>
Some(ErrorKind::FilesystemLoop),
v if v == (ErrorKind::StaleNetworkFileHandle as _) =>
Some(ErrorKind::StaleNetworkFileHandle),
v if v == (ErrorKind::InvalidInput as _) =>
Some(ErrorKind::InvalidInput),
v if v == (ErrorKind::InvalidData as _) =>
Some(ErrorKind::InvalidData),
v if v == (ErrorKind::TimedOut as _) => Some(ErrorKind::TimedOut),
v if v == (ErrorKind::WriteZero as _) => Some(ErrorKind::WriteZero),
v if v == (ErrorKind::StorageFull as _) =>
Some(ErrorKind::StorageFull),
v if v == (ErrorKind::NotSeekable as _) =>
Some(ErrorKind::NotSeekable),
v if v == (ErrorKind::QuotaExceeded as _) =>
Some(ErrorKind::QuotaExceeded),
v if v == (ErrorKind::FileTooLarge as _) =>
Some(ErrorKind::FileTooLarge),
v if v == (ErrorKind::ResourceBusy as _) =>
Some(ErrorKind::ResourceBusy),
v if v == (ErrorKind::ExecutableFileBusy as _) =>
Some(ErrorKind::ExecutableFileBusy),
v if v == (ErrorKind::Deadlock as _) => Some(ErrorKind::Deadlock),
v if v == (ErrorKind::CrossesDevices as _) =>
Some(ErrorKind::CrossesDevices),
v if v == (ErrorKind::TooManyLinks as _) =>
Some(ErrorKind::TooManyLinks),
v if v == (ErrorKind::InvalidFilename as _) =>
Some(ErrorKind::InvalidFilename),
v if v == (ErrorKind::ArgumentListTooLong as _) =>
Some(ErrorKind::ArgumentListTooLong),
v if v == (ErrorKind::Interrupted as _) =>
Some(ErrorKind::Interrupted),
v if v == (ErrorKind::Other as _) => Some(ErrorKind::Other),
v if v == (ErrorKind::UnexpectedEof as _) =>
Some(ErrorKind::UnexpectedEof),
v if v == (ErrorKind::Unsupported as _) =>
Some(ErrorKind::Unsupported),
v if v == (ErrorKind::OutOfMemory as _) =>
Some(ErrorKind::OutOfMemory),
v if v == (ErrorKind::InProgress as _) => Some(ErrorKind::InProgress),
v if v == (ErrorKind::TooManyOpenFiles as _) =>
Some(ErrorKind::TooManyOpenFiles),
v if v == (ErrorKind::InputOutputError as _) =>
Some(ErrorKind::InputOutputError),
v if v == (ErrorKind::Uncategorized as _) =>
Some(ErrorKind::Uncategorized),
_ => None,
}
}from_prim!(ek => ErrorKind {
1063 NotFound,
1064 PermissionDenied,
1065 ConnectionRefused,
1066 ConnectionReset,
1067 HostUnreachable,
1068 NetworkUnreachable,
1069 ConnectionAborted,
1070 NotConnected,
1071 AddrInUse,
1072 AddrNotAvailable,
1073 NetworkDown,
1074 BrokenPipe,
1075 AlreadyExists,
1076 WouldBlock,
1077 NotADirectory,
1078 IsADirectory,
1079 DirectoryNotEmpty,
1080 ReadOnlyFilesystem,
1081 FilesystemLoop,
1082 StaleNetworkFileHandle,
1083 InvalidInput,
1084 InvalidData,
1085 TimedOut,
1086 WriteZero,
1087 StorageFull,
1088 NotSeekable,
1089 QuotaExceeded,
1090 FileTooLarge,
1091 ResourceBusy,
1092 ExecutableFileBusy,
1093 Deadlock,
1094 CrossesDevices,
1095 TooManyLinks,
1096 InvalidFilename,
1097 ArgumentListTooLong,
1098 Interrupted,
1099 Other,
1100 UnexpectedEof,
1101 Unsupported,
1102 OutOfMemory,
1103 InProgress,
1104 TooManyOpenFiles,
1105 InputOutputError,
1106 Uncategorized,
1107 })1108 }
1109}
11101111#[stable(feature = "io_errorkind_display", since = "1.60.0")]
1112impl fmt::Displayfor ErrorKind {
1113/// Shows a human-readable description of the [`ErrorKind`].
1114 ///
1115 /// This is similar to `impl Display for Error`, but doesn't require first converting to Error.
1116 ///
1117 /// # Examples
1118 /// ```
1119 /// use core::io::ErrorKind;
1120 /// assert_eq!("entity not found", ErrorKind::NotFound.to_string());
1121 /// ```
1122fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1123fmt.write_str(self.as_str())
1124 }
1125}