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