std/io/error.rs
1#[cfg(test)]
2mod tests;
3
4#[stable(feature = "rust1", since = "1.0.0")]
5pub use core::io::ErrorKind;
6
7// On 64-bit platforms, `io::Error` may use a bit-packed representation to
8// reduce size. However, this representation assumes that error codes are
9// always 32-bit wide.
10//
11// This assumption is invalid on 64-bit UEFI, where error codes are 64-bit.
12// Therefore, the packed representation is explicitly disabled for UEFI
13// targets, and the unpacked representation must be used instead.
14#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
15mod repr_bitpacked;
16#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
17use repr_bitpacked::Repr;
18
19#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
20mod repr_unpacked;
21#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
22use repr_unpacked::Repr;
23
24use crate::{error, fmt, result, sys};
25
26/// A specialized [`Result`] type for I/O operations.
27///
28/// This type is broadly used across [`std::io`] for any operation which may
29/// produce an error.
30///
31/// This type alias is generally used to avoid writing out [`io::Error`] directly and
32/// is otherwise a direct mapping to [`Result`].
33///
34/// While usual Rust style is to import types directly, aliases of [`Result`]
35/// often are not, to make it easier to distinguish between them. [`Result`] is
36/// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
37/// will generally use `io::Result` instead of shadowing the [prelude]'s import
38/// of [`std::result::Result`][`Result`].
39///
40/// [`std::io`]: crate::io
41/// [`io::Error`]: Error
42/// [`Result`]: crate::result::Result
43/// [prelude]: crate::prelude
44///
45/// # Examples
46///
47/// A convenience function that bubbles an `io::Result` to its caller:
48///
49/// ```
50/// use std::io;
51///
52/// fn get_string() -> io::Result<String> {
53/// let mut buffer = String::new();
54///
55/// io::stdin().read_line(&mut buffer)?;
56///
57/// Ok(buffer)
58/// }
59/// ```
60#[stable(feature = "rust1", since = "1.0.0")]
61#[doc(search_unbox)]
62pub type Result<T> = result::Result<T, Error>;
63
64/// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
65/// associated traits.
66///
67/// Errors mostly originate from the underlying OS, but custom instances of
68/// `Error` can be created with crafted error messages and a particular value of
69/// [`ErrorKind`].
70///
71/// [`Read`]: crate::io::Read
72/// [`Write`]: crate::io::Write
73/// [`Seek`]: crate::io::Seek
74#[stable(feature = "rust1", since = "1.0.0")]
75pub struct Error {
76 repr: Repr,
77}
78
79#[stable(feature = "rust1", since = "1.0.0")]
80impl fmt::Debug for Error {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 fmt::Debug::fmt(&self.repr, f)
83 }
84}
85
86/// Common errors constants for use in std
87#[allow(dead_code)]
88impl Error {
89 pub(crate) const INVALID_UTF8: Self =
90 const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8");
91
92 pub(crate) const READ_EXACT_EOF: Self =
93 const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer");
94
95 pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!(
96 ErrorKind::NotFound,
97 "the number of hardware threads is not known for the target platform",
98 );
99
100 pub(crate) const UNSUPPORTED_PLATFORM: Self =
101 const_error!(ErrorKind::Unsupported, "operation not supported on this platform");
102
103 pub(crate) const WRITE_ALL_EOF: Self =
104 const_error!(ErrorKind::WriteZero, "failed to write whole buffer");
105
106 pub(crate) const ZERO_TIMEOUT: Self =
107 const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
108
109 pub(crate) const NO_ADDRESSES: Self =
110 const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses");
111}
112
113#[stable(feature = "rust1", since = "1.0.0")]
114impl From<alloc::ffi::NulError> for Error {
115 /// Converts a [`alloc::ffi::NulError`] into a [`Error`].
116 fn from(_: alloc::ffi::NulError) -> Error {
117 const_error!(ErrorKind::InvalidInput, "data provided contains a nul byte")
118 }
119}
120
121#[stable(feature = "io_error_from_try_reserve", since = "1.78.0")]
122impl From<alloc::collections::TryReserveError> for Error {
123 /// Converts `TryReserveError` to an error with [`ErrorKind::OutOfMemory`].
124 ///
125 /// `TryReserveError` won't be available as the error `source()`,
126 /// but this may change in the future.
127 fn from(_: alloc::collections::TryReserveError) -> Error {
128 // ErrorData::Custom allocates, which isn't great for handling OOM errors.
129 ErrorKind::OutOfMemory.into()
130 }
131}
132
133// Only derive debug in tests, to make sure it
134// doesn't accidentally get printed.
135#[cfg_attr(test, derive(Debug))]
136enum ErrorData<C> {
137 Os(RawOsError),
138 Simple(ErrorKind),
139 SimpleMessage(&'static SimpleMessage),
140 Custom(C),
141}
142
143/// The type of raw OS error codes returned by [`Error::raw_os_error`].
144///
145/// This is an [`i32`] on all currently supported platforms, but platforms
146/// added in the future (such as UEFI) may use a different primitive type like
147/// [`usize`]. Use `as`or [`into`] conversions where applicable to ensure maximum
148/// portability.
149///
150/// [`into`]: Into::into
151#[unstable(feature = "raw_os_error_ty", issue = "107792")]
152pub type RawOsError = sys::io::RawOsError;
153
154// `#[repr(align(4))]` is probably redundant, it should have that value or
155// higher already. We include it just because repr_bitpacked.rs's encoding
156// requires an alignment >= 4 (note that `#[repr(align)]` will not reduce the
157// alignment required by the struct, only increase it).
158//
159// If we add more variants to ErrorData, this can be increased to 8, but it
160// should probably be behind `#[cfg_attr(target_pointer_width = "64", ...)]` or
161// whatever cfg we're using to enable the `repr_bitpacked` code, since only the
162// that version needs the alignment, and 8 is higher than the alignment we'll
163// have on 32 bit platforms.
164//
165// (For the sake of being explicit: the alignment requirement here only matters
166// if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't
167// matter at all)
168#[doc(hidden)]
169#[unstable(feature = "io_const_error_internals", issue = "none")]
170#[repr(align(4))]
171#[derive(Debug)]
172pub struct SimpleMessage {
173 pub kind: ErrorKind,
174 pub message: &'static str,
175}
176
177/// Creates a new I/O error from a known kind of error and a string literal.
178///
179/// Contrary to [`Error::new`], this macro does not allocate and can be used in
180/// `const` contexts.
181///
182/// # Example
183/// ```
184/// #![feature(io_const_error)]
185/// use std::io::{const_error, Error, ErrorKind};
186///
187/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works");
188///
189/// fn not_here() -> Result<(), Error> {
190/// Err(FAIL)
191/// }
192/// ```
193#[rustc_macro_transparency = "semiopaque"]
194#[unstable(feature = "io_const_error", issue = "133448")]
195#[allow_internal_unstable(hint_must_use, io_const_error_internals)]
196pub macro const_error($kind:expr, $message:expr $(,)?) {
197 $crate::hint::must_use($crate::io::Error::from_static_message(
198 const { &$crate::io::SimpleMessage { kind: $kind, message: $message } },
199 ))
200}
201
202// As with `SimpleMessage`: `#[repr(align(4))]` here is just because
203// repr_bitpacked's encoding requires it. In practice it almost certainly be
204// already be this high or higher.
205#[derive(Debug)]
206#[repr(align(4))]
207struct Custom {
208 kind: ErrorKind,
209 error: Box<dyn error::Error + Send + Sync>,
210}
211
212/// Intended for use for errors not exposed to the user, where allocating onto
213/// the heap (for normal construction via Error::new) is too costly.
214#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
215impl From<ErrorKind> for Error {
216 /// Converts an [`ErrorKind`] into an [`Error`].
217 ///
218 /// This conversion creates a new error with a simple representation of error kind.
219 ///
220 /// # Examples
221 ///
222 /// ```
223 /// use std::io::{Error, ErrorKind};
224 ///
225 /// let not_found = ErrorKind::NotFound;
226 /// let error = Error::from(not_found);
227 /// assert_eq!("entity not found", format!("{error}"));
228 /// ```
229 #[inline]
230 fn from(kind: ErrorKind) -> Error {
231 Error { repr: Repr::new_simple(kind) }
232 }
233}
234
235impl Error {
236 /// Creates a new I/O error from a known kind of error as well as an
237 /// arbitrary error payload.
238 ///
239 /// This function is used to generically create I/O errors which do not
240 /// originate from the OS itself. The `error` argument is an arbitrary
241 /// payload which will be contained in this [`Error`].
242 ///
243 /// Note that this function allocates memory on the heap.
244 /// If no extra payload is required, use the `From` conversion from
245 /// `ErrorKind`.
246 ///
247 /// # Examples
248 ///
249 /// ```
250 /// use std::io::{Error, ErrorKind};
251 ///
252 /// // errors can be created from strings
253 /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
254 ///
255 /// // errors can also be created from other errors
256 /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
257 ///
258 /// // creating an error without payload (and without memory allocation)
259 /// let eof_error = Error::from(ErrorKind::UnexpectedEof);
260 /// ```
261 #[stable(feature = "rust1", since = "1.0.0")]
262 #[cfg_attr(not(test), rustc_diagnostic_item = "io_error_new")]
263 #[inline(never)]
264 pub fn new<E>(kind: ErrorKind, error: E) -> Error
265 where
266 E: Into<Box<dyn error::Error + Send + Sync>>,
267 {
268 Self::_new(kind, error.into())
269 }
270
271 /// Creates a new I/O error from an arbitrary error payload.
272 ///
273 /// This function is used to generically create I/O errors which do not
274 /// originate from the OS itself. It is a shortcut for [`Error::new`]
275 /// with [`ErrorKind::Other`].
276 ///
277 /// # Examples
278 ///
279 /// ```
280 /// use std::io::Error;
281 ///
282 /// // errors can be created from strings
283 /// let custom_error = Error::other("oh no!");
284 ///
285 /// // errors can also be created from other errors
286 /// let custom_error2 = Error::other(custom_error);
287 /// ```
288 #[stable(feature = "io_error_other", since = "1.74.0")]
289 pub fn other<E>(error: E) -> Error
290 where
291 E: Into<Box<dyn error::Error + Send + Sync>>,
292 {
293 Self::_new(ErrorKind::Other, error.into())
294 }
295
296 fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
297 Error { repr: Repr::new_custom(Box::new(Custom { kind, error })) }
298 }
299
300 /// Creates a new I/O error from a known kind of error as well as a constant
301 /// message.
302 ///
303 /// This function does not allocate.
304 ///
305 /// You should not use this directly, and instead use the `const_error!`
306 /// macro: `io::const_error!(ErrorKind::Something, "some_message")`.
307 ///
308 /// This function should maybe change to `from_static_message<const MSG: &'static
309 /// str>(kind: ErrorKind)` in the future, when const generics allow that.
310 #[inline]
311 #[doc(hidden)]
312 #[unstable(feature = "io_const_error_internals", issue = "none")]
313 pub const fn from_static_message(msg: &'static SimpleMessage) -> Error {
314 Self { repr: Repr::new_simple_message(msg) }
315 }
316
317 /// Returns an error representing the last OS error which occurred.
318 ///
319 /// This function reads the value of `errno` for the target platform (e.g.
320 /// `GetLastError` on Windows) and will return a corresponding instance of
321 /// [`Error`] for the error code.
322 ///
323 /// This should be called immediately after a call to a platform function,
324 /// otherwise the state of the error value is indeterminate. In particular,
325 /// other standard library functions may call platform functions that may
326 /// (or may not) reset the error value even if they succeed.
327 ///
328 /// # Examples
329 ///
330 /// ```
331 /// use std::io::Error;
332 ///
333 /// let os_error = Error::last_os_error();
334 /// println!("last OS error: {os_error:?}");
335 /// ```
336 #[stable(feature = "rust1", since = "1.0.0")]
337 #[doc(alias = "GetLastError")]
338 #[doc(alias = "errno")]
339 #[must_use]
340 #[inline]
341 pub fn last_os_error() -> Error {
342 Error::from_raw_os_error(sys::io::errno())
343 }
344
345 /// Creates a new instance of an [`Error`] from a particular OS error code.
346 ///
347 /// # Examples
348 ///
349 /// On Linux:
350 ///
351 /// ```
352 /// # if cfg!(target_os = "linux") {
353 /// use std::io;
354 ///
355 /// let error = io::Error::from_raw_os_error(22);
356 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
357 /// # }
358 /// ```
359 ///
360 /// On Windows:
361 ///
362 /// ```
363 /// # if cfg!(windows) {
364 /// use std::io;
365 ///
366 /// let error = io::Error::from_raw_os_error(10022);
367 /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
368 /// # }
369 /// ```
370 #[stable(feature = "rust1", since = "1.0.0")]
371 #[must_use]
372 #[inline]
373 pub fn from_raw_os_error(code: RawOsError) -> Error {
374 Error { repr: Repr::new_os(code) }
375 }
376
377 /// Returns the OS error that this error represents (if any).
378 ///
379 /// If this [`Error`] was constructed via [`last_os_error`] or
380 /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
381 /// it will return [`None`].
382 ///
383 /// [`last_os_error`]: Error::last_os_error
384 /// [`from_raw_os_error`]: Error::from_raw_os_error
385 ///
386 /// # Examples
387 ///
388 /// ```
389 /// use std::io::{Error, ErrorKind};
390 ///
391 /// fn print_os_error(err: &Error) {
392 /// if let Some(raw_os_err) = err.raw_os_error() {
393 /// println!("raw OS error: {raw_os_err:?}");
394 /// } else {
395 /// println!("Not an OS error");
396 /// }
397 /// }
398 ///
399 /// fn main() {
400 /// // Will print "raw OS error: ...".
401 /// print_os_error(&Error::last_os_error());
402 /// // Will print "Not an OS error".
403 /// print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
404 /// }
405 /// ```
406 #[stable(feature = "rust1", since = "1.0.0")]
407 #[must_use]
408 #[inline]
409 pub fn raw_os_error(&self) -> Option<RawOsError> {
410 match self.repr.data() {
411 ErrorData::Os(i) => Some(i),
412 ErrorData::Custom(..) => None,
413 ErrorData::Simple(..) => None,
414 ErrorData::SimpleMessage(..) => None,
415 }
416 }
417
418 /// Returns a reference to the inner error wrapped by this error (if any).
419 ///
420 /// If this [`Error`] was constructed via [`new`] then this function will
421 /// return [`Some`], otherwise it will return [`None`].
422 ///
423 /// [`new`]: Error::new
424 ///
425 /// # Examples
426 ///
427 /// ```
428 /// use std::io::{Error, ErrorKind};
429 ///
430 /// fn print_error(err: &Error) {
431 /// if let Some(inner_err) = err.get_ref() {
432 /// println!("Inner error: {inner_err:?}");
433 /// } else {
434 /// println!("No inner error");
435 /// }
436 /// }
437 ///
438 /// fn main() {
439 /// // Will print "No inner error".
440 /// print_error(&Error::last_os_error());
441 /// // Will print "Inner error: ...".
442 /// print_error(&Error::new(ErrorKind::Other, "oh no!"));
443 /// }
444 /// ```
445 #[stable(feature = "io_error_inner", since = "1.3.0")]
446 #[must_use]
447 #[inline]
448 pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
449 match self.repr.data() {
450 ErrorData::Os(..) => None,
451 ErrorData::Simple(..) => None,
452 ErrorData::SimpleMessage(..) => None,
453 ErrorData::Custom(c) => Some(&*c.error),
454 }
455 }
456
457 /// Returns a mutable reference to the inner error wrapped by this error
458 /// (if any).
459 ///
460 /// If this [`Error`] was constructed via [`new`] then this function will
461 /// return [`Some`], otherwise it will return [`None`].
462 ///
463 /// [`new`]: Error::new
464 ///
465 /// # Examples
466 ///
467 /// ```
468 /// use std::io::{Error, ErrorKind};
469 /// use std::{error, fmt};
470 /// use std::fmt::Display;
471 ///
472 /// #[derive(Debug)]
473 /// struct MyError {
474 /// v: String,
475 /// }
476 ///
477 /// impl MyError {
478 /// fn new() -> MyError {
479 /// MyError {
480 /// v: "oh no!".to_string()
481 /// }
482 /// }
483 ///
484 /// fn change_message(&mut self, new_message: &str) {
485 /// self.v = new_message.to_string();
486 /// }
487 /// }
488 ///
489 /// impl error::Error for MyError {}
490 ///
491 /// impl Display for MyError {
492 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
493 /// write!(f, "MyError: {}", self.v)
494 /// }
495 /// }
496 ///
497 /// fn change_error(mut err: Error) -> Error {
498 /// if let Some(inner_err) = err.get_mut() {
499 /// inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
500 /// }
501 /// err
502 /// }
503 ///
504 /// fn print_error(err: &Error) {
505 /// if let Some(inner_err) = err.get_ref() {
506 /// println!("Inner error: {inner_err}");
507 /// } else {
508 /// println!("No inner error");
509 /// }
510 /// }
511 ///
512 /// fn main() {
513 /// // Will print "No inner error".
514 /// print_error(&change_error(Error::last_os_error()));
515 /// // Will print "Inner error: ...".
516 /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
517 /// }
518 /// ```
519 #[stable(feature = "io_error_inner", since = "1.3.0")]
520 #[must_use]
521 #[inline]
522 pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
523 match self.repr.data_mut() {
524 ErrorData::Os(..) => None,
525 ErrorData::Simple(..) => None,
526 ErrorData::SimpleMessage(..) => None,
527 ErrorData::Custom(c) => Some(&mut *c.error),
528 }
529 }
530
531 /// Consumes the `Error`, returning its inner error (if any).
532 ///
533 /// If this [`Error`] was constructed via [`new`] or [`other`],
534 /// then this function will return [`Some`],
535 /// otherwise it will return [`None`].
536 ///
537 /// [`new`]: Error::new
538 /// [`other`]: Error::other
539 ///
540 /// # Examples
541 ///
542 /// ```
543 /// use std::io::{Error, ErrorKind};
544 ///
545 /// fn print_error(err: Error) {
546 /// if let Some(inner_err) = err.into_inner() {
547 /// println!("Inner error: {inner_err}");
548 /// } else {
549 /// println!("No inner error");
550 /// }
551 /// }
552 ///
553 /// fn main() {
554 /// // Will print "No inner error".
555 /// print_error(Error::last_os_error());
556 /// // Will print "Inner error: ...".
557 /// print_error(Error::new(ErrorKind::Other, "oh no!"));
558 /// }
559 /// ```
560 #[stable(feature = "io_error_inner", since = "1.3.0")]
561 #[must_use = "`self` will be dropped if the result is not used"]
562 #[inline]
563 pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
564 match self.repr.into_data() {
565 ErrorData::Os(..) => None,
566 ErrorData::Simple(..) => None,
567 ErrorData::SimpleMessage(..) => None,
568 ErrorData::Custom(c) => Some(c.error),
569 }
570 }
571
572 /// Attempts to downcast the custom boxed error to `E`.
573 ///
574 /// If this [`Error`] contains a custom boxed error,
575 /// then it would attempt downcasting on the boxed error,
576 /// otherwise it will return [`Err`].
577 ///
578 /// If the custom boxed error has the same type as `E`, it will return [`Ok`],
579 /// otherwise it will also return [`Err`].
580 ///
581 /// This method is meant to be a convenience routine for calling
582 /// `Box<dyn Error + Sync + Send>::downcast` on the custom boxed error, returned by
583 /// [`Error::into_inner`].
584 ///
585 ///
586 /// # Examples
587 ///
588 /// ```
589 /// use std::fmt;
590 /// use std::io;
591 /// use std::error::Error;
592 ///
593 /// #[derive(Debug)]
594 /// enum E {
595 /// Io(io::Error),
596 /// SomeOtherVariant,
597 /// }
598 ///
599 /// impl fmt::Display for E {
600 /// // ...
601 /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602 /// # todo!()
603 /// # }
604 /// }
605 /// impl Error for E {}
606 ///
607 /// impl From<io::Error> for E {
608 /// fn from(err: io::Error) -> E {
609 /// err.downcast::<E>()
610 /// .unwrap_or_else(E::Io)
611 /// }
612 /// }
613 ///
614 /// impl From<E> for io::Error {
615 /// fn from(err: E) -> io::Error {
616 /// match err {
617 /// E::Io(io_error) => io_error,
618 /// e => io::Error::new(io::ErrorKind::Other, e),
619 /// }
620 /// }
621 /// }
622 ///
623 /// # fn main() {
624 /// let e = E::SomeOtherVariant;
625 /// // Convert it to an io::Error
626 /// let io_error = io::Error::from(e);
627 /// // Cast it back to the original variant
628 /// let e = E::from(io_error);
629 /// assert!(matches!(e, E::SomeOtherVariant));
630 ///
631 /// let io_error = io::Error::from(io::ErrorKind::AlreadyExists);
632 /// // Convert it to E
633 /// let e = E::from(io_error);
634 /// // Cast it back to the original variant
635 /// let io_error = io::Error::from(e);
636 /// assert_eq!(io_error.kind(), io::ErrorKind::AlreadyExists);
637 /// assert!(io_error.get_ref().is_none());
638 /// assert!(io_error.raw_os_error().is_none());
639 /// # }
640 /// ```
641 #[stable(feature = "io_error_downcast", since = "1.79.0")]
642 pub fn downcast<E>(self) -> result::Result<E, Self>
643 where
644 E: error::Error + Send + Sync + 'static,
645 {
646 if let ErrorData::Custom(c) = self.repr.data()
647 && c.error.is::<E>()
648 {
649 if let ErrorData::Custom(b) = self.repr.into_data()
650 && let Ok(err) = b.error.downcast::<E>()
651 {
652 Ok(*err)
653 } else {
654 // Safety: We have just checked that the condition is true
655 unsafe { crate::hint::unreachable_unchecked() }
656 }
657 } else {
658 Err(self)
659 }
660 }
661
662 /// Returns the corresponding [`ErrorKind`] for this error.
663 ///
664 /// This may be a value set by Rust code constructing custom `io::Error`s,
665 /// or if this `io::Error` was sourced from the operating system,
666 /// it will be a value inferred from the system's error encoding.
667 /// See [`last_os_error`] for more details.
668 ///
669 /// [`last_os_error`]: Error::last_os_error
670 ///
671 /// # Examples
672 ///
673 /// ```
674 /// use std::io::{Error, ErrorKind};
675 ///
676 /// fn print_error(err: Error) {
677 /// println!("{:?}", err.kind());
678 /// }
679 ///
680 /// fn main() {
681 /// // As no error has (visibly) occurred, this may print anything!
682 /// // It likely prints a placeholder for unidentified (non-)errors.
683 /// print_error(Error::last_os_error());
684 /// // Will print "AddrInUse".
685 /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
686 /// }
687 /// ```
688 #[stable(feature = "rust1", since = "1.0.0")]
689 #[must_use]
690 #[inline]
691 pub fn kind(&self) -> ErrorKind {
692 match self.repr.data() {
693 ErrorData::Os(code) => sys::io::decode_error_kind(code),
694 ErrorData::Custom(c) => c.kind,
695 ErrorData::Simple(kind) => kind,
696 ErrorData::SimpleMessage(m) => m.kind,
697 }
698 }
699
700 #[inline]
701 pub(crate) fn is_interrupted(&self) -> bool {
702 match self.repr.data() {
703 ErrorData::Os(code) => sys::io::is_interrupted(code),
704 ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
705 ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
706 ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
707 }
708 }
709}
710
711impl fmt::Debug for Repr {
712 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
713 match self.data() {
714 ErrorData::Os(code) => fmt
715 .debug_struct("Os")
716 .field("code", &code)
717 .field("kind", &sys::io::decode_error_kind(code))
718 .field("message", &sys::io::error_string(code))
719 .finish(),
720 ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
721 ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
722 ErrorData::SimpleMessage(msg) => fmt
723 .debug_struct("Error")
724 .field("kind", &msg.kind)
725 .field("message", &msg.message)
726 .finish(),
727 }
728 }
729}
730
731#[stable(feature = "rust1", since = "1.0.0")]
732impl fmt::Display for Error {
733 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
734 match self.repr.data() {
735 ErrorData::Os(code) => {
736 let detail = sys::io::error_string(code);
737 write!(fmt, "{detail} (os error {code})")
738 }
739 ErrorData::Custom(ref c) => c.error.fmt(fmt),
740 ErrorData::Simple(kind) => kind.fmt(fmt),
741 ErrorData::SimpleMessage(msg) => msg.message.fmt(fmt),
742 }
743 }
744}
745
746#[stable(feature = "rust1", since = "1.0.0")]
747impl error::Error for Error {
748 #[allow(deprecated)]
749 fn cause(&self) -> Option<&dyn error::Error> {
750 match self.repr.data() {
751 ErrorData::Os(..) => None,
752 ErrorData::Simple(..) => None,
753 ErrorData::SimpleMessage(..) => None,
754 ErrorData::Custom(c) => c.error.cause(),
755 }
756 }
757
758 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
759 match self.repr.data() {
760 ErrorData::Os(..) => None,
761 ErrorData::Simple(..) => None,
762 ErrorData::SimpleMessage(..) => None,
763 ErrorData::Custom(c) => c.error.source(),
764 }
765 }
766}
767
768fn _assert_error_is_sync_send() {
769 fn _is_sync_send<T: Sync + Send>() {}
770 _is_sync_send::<Error>();
771}